So this is my structure:
HTML form sends authentication to nodejs.
Authenticate using passportjs > res.send the userid with jwt-simple (json web token).
The received info is saved in $localStorage.user. I use that info in any of the controllers needed and include it and send my post/get requests to nodejs.
I decode the info in nodejs and query the DB.
Is this safe? Is this how it works in real world?
Many thanks.
#Somename:
The workflow which you have mentioned is slightly correct.
The ideal way to get passport authentication done is,
User log's in entering his username and passport.
Send a post request with these form data.
Authenticate the credentials using Passport. Using the passport.authenticate will invoke the serializeUser and get you the valid user if it exists. Else we return a login error response.
A Successful login will automatically create a session in back end, save it in the sessionStorage and adds it with the response.
This cookie will be saved automatically into browser's local storage once the response is fetched at client side.
Every time we send a subsequent API request we need to include this cookie in the req headers.
This cookie should be validated each time in back end. passport.authorize will again make use of the cookie and check if the session is valid.
Logout session once the User logs out.
Hope I've made things clear for you.
Related
I have React signIn form and sessions mechanism implemented in NodeJs. In React I have protected routes only for authenticated users.
How should I check if user is authenticated. I have two ideas:
If user sign in for the fisrt time I can save this information in LocalStorage and then evrytime just check localStorage.
Send request to NodeJS server every time to check if user is authenticated.
Do you have any other ideas? Which solution should I pick?
I tried both options and second one is more UI unfriendly becasue I have to run loading state evrytime I am waiting for auth response. On the other hand, first option has also disadvantege, because I am based on token in LocalStorage which can be malicious.
Every time a request is made to an endpoint that requires authentication, the request should contain proof that they are who they claim to be.
The classic way to do this is by storing some sort of "Session ID" in a cookie or localStorage (client side), that you send along with every request.
Using a "Token" (e.g: JWT) instead of a "Session ID" is another popular way to handle authentication.
Check out this article for more information about both: https://dzone.com/articles/cookies-vs-tokens-the-definitive-guide
To return to your question, I'm not sure what you're worried about in regards to a "malicious Token in localStorage" (Or do you mean localStorage can be malicious?). But for a secure application you have to either:
Store something client-side
Require your user to provide credentials (username + password) for every request
I am using Session Authentication for my Django REST API. What I want is to be able to access self.request.user every time an API call is received at any of my endpoints, so I can process user generated content.
From the docs, it seems session authentication stores only session id's in cookies, but does not send any data beyond that. So, even after I log in, the subsequent requests I send are user-anonymous.
One solution is to send the username and password every time a call is made from the origin, which I think is probably not good practice.
How can I go about persisting user in a session?
You can use JWT Authentication and send the token with every request, this way you can access request.user in your code.
I have to deploy a login page with profile with node js, mongodb and angularjs. Can you suggest me an example of MEAN in mongoDB and not in mongoose? I have to store credentials user's with mongodb and I have to send user's data to the client, not in json.
Thanks
Mongoose is a interface to connect to mongo databases in NodeJs environment. To perform login and send data to client, you can follow these steps:
Send a login request to server.
Verify the user credentials and send a token back to user for proceed with further requests for client data. For this, you can use JWT.
Put an interceptor in angularjs which will automatically associate the token in header with each request corresponds to valid user.
At server end, you can check whether requests consist of token or not. If not, you can send unauthorized in response (401).
I am having troubles in implementing OAuth in the right way.
I use a client/API architecture (Angular for front and Node.js for back) and I would like user to sign in using Google OAuth authentication only.
Here is what I think is the right way for the moment (tell me if I misunderstood something) :
Angular open a Google popup asking user's consent.
Once the user agree, Google Authorization server sends back to angular a verification code.
This verification code is forwarded to an API endpoint.
Then, the API asks Google Authorization server to exchange this code for an access_token, an id_token and a refresh_token.
Google sends those 3 tokens.
The API uses access_token to retrieve user from Google API
The API persists the user
Here is the little dillema, in my opinion, the access_token and refresh_token should be stored into the database and the id_token should be sent back to Angular client.
This way, it would allow the API to ask for resource in Google API and if the token expires it can still ask for a new token thanks to the refresh_token.
Client-side, the id_token is embedded in all requests thus allowing the API to identify the client and verify his authentication with Google certs from https://www.googleapis.com/oauth2/v3/certs.
Supposing this is right way to use tokens, how could I deal with id_token expiration since client does not have any refresh token ?
Thanks !
I do it slightly different (I have the same basic architecture though).
Angular decides the user needs to log in and displays a login popup.
The url in the login popup is not serviced by angular, but is instead directly run off of the backend server: /auth/google . (I use hapijs and bell, personally).
/auth/google is serviced by a bell plugin and initiates the OAUTH dance.
the end of the OAUTH dance results in my node server generating a local token (I just generate random bytes and store them in redis mapped to user ids)
because the initial login popup was created by window.open, the success page (generated on the api side rather than in angular) can use window.opener.postMessage to communicate the token back to the angular runtime.
This way, all my sensitive google credentials (the user's oauth token, refresh token if needed, and my application's api ID and secret) are only on the server, except for during the OAUTH dance relay when they're in a URL string during the client redirects. This is reasonably secure.
Then for all the actual user interactions with the api, I use the token I generated in step four to authenticate. This could be a JWT if you wanted, but I don't do it that way; I just use redis to map from 'longrandostring' -> userId. That lets me (for example) force everyone to re-login if I wipe the redis database that has all the tokens stored, or I can write a lua script to delete all the entries that map to a certain userid.
If you need a refresh token, you can set access_type=offline in the initial request to oauth2/auth, and you'll get a refresh token as part of the response, unless you've previously gotten a refresh token. You can then persist it on the server side and get new access tokens as needed. If you set approval_prompt=force as well, you'll force a new consent screen and be guaranteed a refresh token (but after some small number of refresh tokens granted to a user, older ones expire on the same application so it's best to only request them if really needed).
I store user auth info and token in a cookie locally for my angular/typescript SPA. Cookie expires after a certain time I have set. How do I reset expiration while user's activity? (session on the server is reset on users requests)
I mean what would be the best way, so I don't code some stupid stuff.
Thank you
I assume you do your authentication and generation of the cookie on the server and your angular side authentication is located in a service.
One way to achieve what you are looking for is to create a method in your client side service to send a request to a known end point of the server which would refresh the cookie. This server endpoint will refresh the cookie and will return a HTTP 200 code.
Once you have this code in place, you can call it when the user interact with the application (ex navigation across views via $locationChangeStart, $routeChangeStart etc).