I am by no means an oauth2 expert and am open to suggestions.Ok, I have setup an Oauth2 server and I am having a problem deciding on the flow when registering a new user from an application.
The user registration form sits on the client and not on the oauth2 server.
1.user goes to example.com/register
2.user fills in the form and clicks send
3.I send a request to my oauth 2 server with the client_credentials grant and scope to receive an token on behalf of the client/app.
I send a request to POST /users/register with the form values using the token from the previous request.
If registration has failed I list the validation rules in a json array.
6.If registration was successful i use the scope originally used to generate the new access token for the user.This is then returned.The user is also flagged as inactive in the db.
7.I have to activate the user somehow and send a request to GET /users/activate using my user token ftom the previous requst.
My question is,does this flow sound right and what should i send as the link in for the activation email?
Your response would be appreciated.
After point 6. When new user is created, back-end should create some unique string or code or (token or hash) which is used to activate the user. Then in email could be like link with /users/activate/(token or hash) after the URL (as pathparameter). Now when the user clicks it, it makes GET request to your endpoint with the unique hash or token and now the back-end can identify the hash or token and activate the user whom the unique hash or token belongs to. So the token or hash is one-to-one relation with user and can be used only once, when it is used it is deleted from DB.
Related
I am not clear on what exactly I should do with the id token from Google after the initial verification.
I'm developing on expo/react native and get the id token locally. Then, I send it to my server and verify it using google client libraries. Once it's verified what should I do with it?
Ideally I could use it to protect my api routes (express) but id tokens expire after 1 hour and I'm not sure how to refresh them with the client library. So, I don't know how I would do this.
Is that the intended use for id tokens? Should I instead be signing my own jwt and sending that back to the client? Then, the client could send that in the auth header of each request to a protected routes.
Google says:
After you have verified the token, check if the user is already in your user database. If so, establish an authenticated session for the user. If the user isn't yet in your user database, create a new user record from the information in the ID token payload, and establish a session for the user. You can prompt the user for any additional profile information you require when you detect a newly created user in your app.
https://developers.google.com/identity/sign-in/ios/backend-auth
Do I use the id token to "establish a session for the user"?
Yes, the ID-token is only used to create the local session, perhaps also create a local entry in your local database if that is used.
The ID token also have a very short lifetime, like 5 minutes in some systems. So it has no long-term use.
The ID token is intended to authenticate the user. It gives you information about the authenticated user, it should not be used to allow access to your endpoints. Access tokens or sessions are intended to do so. So in your case, you should do exactly as your gut feeling tells you - create a session for the user basing on the data you got in the ID token.
If you have your own Authorization Server you can use the ID token to issue an access token and return the token to the frontend app, then use the access token to access your backends. Have a look at OAuth flows if you would want to go this way.
I'm building a Landing Page in React where a visitor submits some data (including name and phone) and this data is sent over HTTP to a Rails 4.2 Backend.
Now, in order for the Landing Page to be able to POST data to the backend, there needs to be some sort of authentication, as only a registered staff member should have access to the data. The Rails backend currently uses regular Devise user/password login to the backend.
I thought about making a dummy account and hardcode an authorization token on the POST header from the landing page, but this is obviously a big security flaw as anyone can see the hardcoded token when they submit the form.
How can I secure the Landing Page to send / receive data to the backend server in a user-agnostic way (since visitors don't make accounts, they just fill a form with their details)?
I am not rails user. But as for your API, like almost all the RESTful API backend, I would assume that rails has the concept of public/private API. I would make the API for getting data from the user public, so that people can send their information without authentication and the other API routes private.
In java spring framework, I can allow an API route to accessible by everyone, like login and generic(no private info) API routes and every other API routes are private which requires Authentication(like an auth-token).
When, you do the login flow and the user has entered the password and hit send, Once your backend authenticates the details, you would have to create an signed authorization token using maybe JWT** ( Json web token ) and send this authorization token to the front-end.
Then, Whenever the front-end makes a call to the backend, it has to attach this token in the header before making the API call. And the back-end should de-code the token to find out which user is requesting it and if the ttl* is within the limits as the issuing token.
If both the cases pass, the back-end should send the requested data or it should send a HTTP CODE - 403/Forbidden, which should then be handled in the front-end to logout the user and open up the login page again.
*(Time to live calculated based on the hours this token is valid from the time of issuing/login)
** JWTs are basically base-64 encoded data ( and signed with a unique key by your backend ) of the user's data. A decoded JWT token of a user would most likely look like this :
{
userIs : "0000-aa12-bb43-cd18",
userName : "Some name",
ttl : "Time to live of this token"
}
I'm trying to use the Hapi's plugin Crumb to implement a solution againts CSRF attacks, but seems that I didn't get the solution flow.
I could simply set a token in each http response as a cookie. And here comes the question, how REST can validate CSRF token, if token issued by client? How REST backend understand what this random string is valid for this request and another random string is not?
It's not possible to generate CSRF token on the client. It should be send from server to client first, and some JS frameworks extract it automatically from the cookie and send it to the server.
The basic idea is that user is supposed to send token along with a cookie and also in the post data. Here is a simple example. If attacker will trick a user to send a particular request to a service, for instance malicious website can have an image with this link src="gmail.com/deleteaccount=true". If user is logged in to gmail. Gmail will think that it was a user who made the request, because cookie send along with request is valid. So, in order to make sure that it was actually a user, gmail also requires a token send with a request data: so instead of gmail.com/deleteaccount=true it needs gmail.com/deleteaccount=true&token=987y23459827345sdfg. Token have to match the one stored in the cookie. So when request is received by a server, it checks if token in the cookie equals to token in the request body. Attacker have no access to user's cookies and don't know the token.
Here is the simplified data flow:
In more details it looks like this:
1) User sends GET request to a server
2) Server sets the cookie with
sessionid, and saving session data with the token
3) server returns HTML with a form containing token in a hidden field.
4) User submits
form, along with a hidden field
5) server compares token from the
submitted form (hidden field) with the token saved in the session storage. If they match, it means that form is submitted by a user.
Here is another grate answer: Why is it common to put CSRF prevention tokens in cookies?
I have used OOB callbacks with desktop and mobile applications for twitter oAuth. But now I am moving onto the web based authentication for my web application consuming twitter api.
I have the following flow of events:
User fills a registration form(with say n fields+) entering his email id and twitter handle.
This generates the(short-lived) twitter request token and the url for obtaining twitter Access Token and secret.
That url is sent to the user's email id, so that it serves the dual purpose of verifying the twitter handle and email id.
Now my question is:
Can I specify the callback URL with parameters so that when the user is redirected back to the application controller, the database receives the entries of the n form fields?
And also once the user is redirected back to the application, is it that the access token is appended to the callback URL (along with the parameters)? If yes, then how do I get the access token (token key and secret)?
To further clarify, consider the callback url:
http://www.someurl.com/controller?param1=val1¶m2=val2
and on redirect to this url, I think(is it?) that twitter appends some params to this url, like
http://www.someurl.com/controller?param1=val1¶m2=val2&someParamsAppendedByTwitter=someValue
I just want to know what this someParamsAppendedByTwitter is/are.
The biggest issue with this question is that in almost all languages, twitter authentication is being dealt with some sort of plugins/libraries and there are very less resources on the same if you want to do it all by yourself.
I'm developing a YouTube application that needs to have a User table with the usual data associated with it in the database. I've decided to go the OAuth route for this application and have 2 tables, one of the AccessToken and one of the RequestToken.
I'm not sure what is to be linked up to a User table of some sort, would it be the access token or the request token?
If the token expires would I just lookup which user has that token then update it?
To sign the user out do I just delete the token for the user and clear the token from the session?
EDIT: In other words, I basically want a user to not have to register to my site but to just login via OAuth and have my application create a user entry in the User table so all of my other data can be linked up to that.
There are two parts to this: login and resources.
If you only want to use YouTube for login, you don't need to store the access token at all. When the user comes back from YouTube with the access token, you make one call to get their YouTube id (not sure if YouTube supports an extension parameter with the id in the token response) and discard the access token. If you also want to make other calls to access the user's YouTube data, you need to keep the access token.
A common way to implement this is:
When the user visits your site you set a session cookie with some random string we call state.
The user clicks on 'Sign In with YouTube'
You go and get a request token from YouTube, then either store it in some local cache (can be a database, redis, memory if this is a small scale app, memcache, etc.) or encrypt it and store it in another cookie on the client. When you make the request token call, include a 'state' parameter in the callback with the value set as cookie in #1. This is a critical security defense against CSRF. Also, your redirection endpoint should use SSL.
You redirect the user to YouTube with the request token (and optionally the encrypted request token secret cookie)
The user logs into YouTube, approves the application, then gets redirected back
You check that the user coming back to the redirection endpoint matches the user you originally sent over by comparing the value of the incoming state parameter with that of the session cookie from the user.
Fetch the request token secret from local cache or by decrypting the token secret cookie used earlier (which ever method you decided to use) and request an access token
Using the access token, make a YouTube API call to get the user information
Lookup in your database to see if you already have a user with that YouTube id. If you do, this is just a login, and if not, this is a new user registration so create a new record for them in your users table.