I am using MEAN stack for developing a web application. I choose it be completely RESTFULL that is stateless. For authentication I am using JWT(Json Web Token) strategy.
Client sends login request to server, server authenticates and sends JWT and user data to the client(here angular 2).I am storing this JWT token in the cookie.
Now my question is how do we store/display user details in the view continuously. For eg if we consider Facebook as restful , after a user logs in, client display user data such as profile image, profile link etc etc.
Since Rest Authentication just retrieves the data, with credentials sent in each request.
How are these user related data retained in the client side. Is it like for each request, user data is fetched from the server and updated continuously in the view.
If yes how or if no then am I missing something.
I know this question might be nonsense to experts, but any advice, suggestion or kickstarter information would be helpful for a novice like me.Are there any best practises for these?
Thanks in advance
Yes, you can fetch user data from server on every request but the right approach is to store it in JWT token as custom claims and on each request get the token from cookie, decode it and get the necessary details from those custom claims.
By the way, you can store user data in localStorage for frequent use.
Related
We have an application that loads information(user specific) from the external system upon successful authentication, to avoid round trips to the external system for each api call, we are planning create a custom JWT token with user specific information for the first time user authenticated, then the token is send to user in each response header using http interceptor and in the front-end we are including the custom token in every request along with authorization token. Is this correct approach? Do you have any alternative suggestions?
I have looked into other distributed caching techniques like redis but not so appealing for a small usecase. Our payload length does not exceed 4 to 5K hence inclined towards the JWT option
it is ok to include user information that allows you to handle the user authorization inside the access token. Just beware of the privacy implication and perhaps not include personal information like social security number or date-of-birth or other identifiable information.
Also, make sure the token size does not get to big. The other option is to lookup and cache the user information in the API's when it receives a new access token.
Some systems including ASP.NET Core do store the token inside the session cookie in an encrypted form, so that the end user can't see or access the stored tokens.
If you are developing a SPA application, the using the BFF pattern is one approach.
There is a lot of good content on the internet that explains how to secure a Spring API with Keycloak: Create a Client that represents the API Service in Keycloak and use a link like the one below to get the access and refresh token:
<Domain>/auth/realms/<realm>/protocol/openid-connect/auth/{some parameters}
This yields both tokens. So far so good.
Now, however, I am not sure how the flow for the frontend accessing the API should look like.
Should the frontend directly access this endpoint and, therefore, obtain the access and refresh token? That would mean that the API can only have the access-type public because there is no way to store the client (the API) secret securely.
Or should there be a third server that somehow stores the refresh token for each user, that the user can call if his access token is no longer valid. This server would then use the client's refresh token (and the client secret that could be stored securely, since it would be in the backend) to get a new access token from Keycloak and would forward it to the user.
I guess the main question that I am asking is, whether the client/user should get the refresh token.
If one needs to implement a logic according to the second option, I would be interested in a link or description of how something like this can be done in Spring.
I think, in either case you need to use the Authorization Code Flow. The implicit flow, which was recommended for SPAs (frontends without a backend server) in former versions of OAuth2 must not be used anymore.
The best option is to have a backend server, so the user retrieves the auth code via redirection and the backend server exchanges this auth code with the access and refresh tokens (and keep them without forwarding them to the frontend).
If there is no backend in place and your frontend needs to retrieve and hold the tokens directly, I would recommend to use the Authorization Code Flow with a public client and the PKCE extension (which - put simply - ensures that the entity asking for the auth code is the same as the entity asking for the tokens and that the auth code was not stolen and used by a foreign entity). There are several sources with more detailed explanations, which might help you, for example: https://auth0.com/docs/flows/authorization-code-flow-with-proof-key-for-code-exchange-pkce
Hope this helps you with your architectural considerations.
I have more conteptual question, how exactly should I handle social login in my project.
The use case is that I would like to allow user to login with Facebook, and keep on my backend information about this user (email, firstname, lastname)
I have some proposal Flow, but I'm not sure if it's a proper approach.
Let's say that I have application architecture as above. Now I would like to explain step-by-step full success flow.
Client (Vue application) make a call to AuthProvider (Facebook)
AuthProvider returns access_token
Client after reciving access_token make a call to backend endpoint like /fb_profile with access_token and userID (?)
Backend make a call to AuthProvider to check if given by client access_token is valid or not.
AuthProvider returns information about user. Backend after getting information about user, save it to database and generate new JWT token
Backend returns generated token to user
Now my question is - Is this good approach? Or should i handle it in other way? Like keep more logic to backend part? Instead of make a call to Facebook from Client, maybe should I make a call to backend, and backend make a call to Facebook?
You seem to be on right track. There could me many ways to do the same thing, here is the way which is working for me using vue/laravel/passport/socialite/github.
Trigger redirect in controller from frontend,
Provider(here github app) is triggered in browser with its url using client id/app name saved in back end config/env. Fill out your login details
It will redirect as created in provider and configured in backend-> show it on frontend, in my case its
http://localhost:8080/authorize/github/callback
From frontend now trigger callback in controller, it will check if user details already exist and will insert if its first time user as per logic. Then it will send back access_token to frontend which can be used in frontend for all the operations
DB
The above will be the sequence of the request flow ( same as yours ).
This would be the standard practice we used to integrate with Facebook. In this case, I strictly advise you to use the JavaScript SDK for Facebook.
Refer below link in case if you run into the following issue:
Vuejs component wait for facebook sdk to load
I'm creating an API server which will be consumed by a mobile app that I will work on later. I have yet to see any reference of API best practices related to user flow and returned data even after searching for several hours.
My question is whether the login response of an API should return the a personal access token with the refresh token along with the user info? Or should I just return the token and make another API call for getting the user info.
I could just do what I have in mind but I'm trying to learn the best practices so that I don't have to adjust a lot of things later.
I need suggestions as well as good references related to my question.
Thank you.
It depends on what you are using for your authentication. If you are using libraries like Laravel Passport or JWT, you can have the token endpoint which returns the access token, refresh token, validity period and the token type (Bearer). You can then have an authenticated endpoint which will be used to get a user's profile based of the token passed in the request header.
However, if you go through the documentation for those libraries, in most there is an allowance to manually generate a token. You can use this in a custom endpoint that will return the token as well as the user profile Passport Manually Generate Token.
If you are using JWT, you can also embed a few user properties in the token itself. The client can the get the profile info from the JWT itself without having to make a round trip to the server. Passport ADD Profile to JWT
If you have a custom way in which you are handling authentication, you can pass the token as well as the user profile in the same response.
In the end, it's up to you to decide what suits you best.
Have you looked at OpenID Connect? It's another layer on top of OAuth 2.0 and provides user authentication (OAuth 2.0 does not cover authentication, it just assumes it happens) and ways to find information about the current user.
It has the concept of an ID_token, in addition to the OAuth access token, and also provides a /userinfo endpoint to retrieve information about the user.
You could put user information in your access token, but security best practice is to NOT allow your access token to be accessible from JavaScript (i.e. use HTTP_ONLY cookies to store your access token).
There are SNS application with 2 servers. Web backend server and REST API server.
The web server allows user login/logout with username/password, and show user information
The REST API server provides APIs like /topics, /comments, it should be stateless without session
The REST API will serve other web applications
There are some potential solutions, but neither is security.
Base Auth, the browser hold the username/password
Token with expiry timestamp, the problem is user could stay on the page until token expires
So, is there a way to protect the REST API when calling it from AJAX?
If I have understood your problem correctly I may suggest you use the Token solution. In order to maintain security you may generate new token on every request (& send it to client in response), which should be used to make next request, and disable token if it is once used or has expired.
Sorry, I meant to mention it as a comment, but I don't have enough reputation.