Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving user session in local storage #10

Open
SimonLab opened this issue Feb 19, 2020 · 3 comments
Open

Saving user session in local storage #10

SimonLab opened this issue Feb 19, 2020 · 3 comments
Assignees
Projects

Comments

@SimonLab
Copy link
Member

Now that the application receives a jwt on authentication we can start to manage the user session in a Elm model.

  • When the application is loading, check for existing user in local storage
  • On authentication get user information from jwt. This might mean sending another request to the server (e.g. get request to /person/info with jwt in header). Save the user information in Elm model and in local storage
@SimonLab SimonLab added the T4h label Feb 19, 2020
@SimonLab SimonLab self-assigned this Feb 19, 2020
@SimonLab SimonLab added this to To do in dwyl app via automation Feb 19, 2020
@SimonLab SimonLab moved this from To do to In progress in dwyl app Feb 19, 2020
@SimonLab
Copy link
Member Author

SimonLab commented Feb 20, 2020

When the elm application is initialised we can pass the user information stored in local storage as flag:

       <script>
            flags = localStorage.getItem('store'); // get the value linked to the key "store"

            Elm.Main.init({flags: flags});
        </script>

localStorage is saving key/value data where the data represent the person information as a stringify json. You can use the functions setItem and removeItem to manage the data in local storage.

On the Elm side, the init function will now takes a flag parameter:

init : Maybe String -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )

Here the flag is represented as a Maybe String. So the value can be Nothing i.e. localStorage.getItem returns null or Just str where str represents the stringify json.

From there we can decode the flag to a specific Elm type.
I've decided to represent a session with:

type Session = Guest | Session Person

type alias Person = {email: String, token: String}

The session can be a guest or a person.

Then in the init function we can use json decoder to match the Session type values:

       session =
            case flag of
                Nothing ->
                    Guest

                Just str ->
                    case decodeString (map2 Person (field "email" string) (field "token" string)) str of
                        Ok p ->
                            Session.Session p

                        _ ->
                            Session.Guest

It tooks me a bit of time to manage to decode the flag to this type. I'm still not sure this is the best solution, however it works. If the string stored in the local storage can't be decoded to the type (wrong json, doesn't contain email or token fields, not a valid json...) the application will convert the person to a Guest.

see also

SimonLab added a commit that referenced this issue Feb 27, 2020
@SimonLab SimonLab mentioned this issue Feb 27, 2020
SimonLab added a commit that referenced this issue Feb 27, 2020
@SimonLab
Copy link
Member Author

SimonLab commented Mar 4, 2020

I'm currently working on redirecting the user after authentication to a specific page (home page in my case but this can be change easily for example if we want to display a profile page on authentication).

Elm provide the Nav.replaceUrl function:
image

We can see this function take as first parameter a Nav.Key value:
image

At the moment this key is stored on the main model:

app-mvp-elm/src/Main.elm

Lines 40 to 43 in f33382b

type alias Model =
{ key : Nav.Key
, page : Page
}

This is an issue when I try to redirect from a specific page as I don't have access to this value:

We can see that all the pages' model contain a session. So a solution to have access to the Nav.Key value is to store it in the session model. This will allow us to manage navigation more easily. We can for example redefine the model as:

type Session
    = Guest Nav.Key
    | Session Nav.Key Person

@SimonLab
Copy link
Member Author

SimonLab commented Mar 5, 2020

The session is now working on localhost (ie login, logout, redirects to home page...) and I'm now making sure that the backend apis are also up to date.
At the moment the redirection to the home page after login is not working as there is an error while getting the user information with the apis hosted on Heorku (I just need to deploy the latest version of the app). So at the moment I'm getting back a 404 response.
When receiving an error from the api (404, 401 or 500) we should redirect on the elm side the user to the correct error page.
So we need to update the following part of the code to redirect the user:

-- if a 401 redirect to 401 page not authorised
Err e ->
( model, Cmd.none )

SimonLab added a commit that referenced this issue Mar 5, 2020
@SimonLab SimonLab moved this from In progress to Awaiting review in dwyl app Mar 5, 2020
SimonLab added a commit that referenced this issue Mar 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
dwyl app
  
Awaiting review
Development

No branches or pull requests

1 participant