I have implemented Token Authentication in my api. When I send a POST request with user credentials, I get back the token. But I can't seem to figure how to implement client side logic to use this token. I mean do I store it somewhere?
From Django Rest Framework Docs
For clients to authenticate, the token key should be included in the Authorization HTTP header. The key should be prefixed by the string literal "Token", with whitespace separating the two strings. For example:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b1
So indeed, you need to store somewhere on the front-end.
You can read more about where is best place to store tokens here and here.
Related
I'm a little bit confused by the documentation. It's said:
Passport includes an authentication guard that will validate access
tokens on incoming requests. Once you have configured the api guard to
use the passport driver, you only need to specify the auth:api
middleware on any routes that require a valid access token.
So it means that Passport utilizes guards not to authenticate users but to validate access tokens on routes where these tokens are required. Did I get that right?
In this case, validating the access token is authenticating the user. To understand why this is the case, let's walk through a simplified authentication flow using JWTs (let's ignore oAuth2 for a bit).
The user is logging in on the website. This triggers a POST /login request, with the username and the password in the request body.
The backend validates the users credentials. If the credentials are valid, it will issue a JWT, which will act as an access token. The JWT payload will contain some data that allows the backend to identify a user, e. g. the user id. The JWT then is signed with a secret that only the backend knows.
The backend will return the access token to the client, who has to include the access token in any subsequent requests to the server. Usually, the client will provide the token in the Authorization header.
When handling the next request from the client, the backend will extract the access token from the Authorization header and check its signature. If the signature is valid, the backend can be sure that the token data has not been manipulated, e. g. by changing the user id on the access token. With a valid signature, the backend can extract the user id from the tokens payload and set the User model for that specific id as authenticated. With an invalid signature, the backend will probably return something like 401 Unauthorized.
What I want to achieve:
Safely allow users to connect their accounts to different social medias using a Single Page Application.
What I am doing:
I am using an SPA and therefor utilizing JWT as my user authentication method. I am passing the JWT token in the OAuth call with Laravel Socialite like this:
return Socialite::driver($provider)
->with(['provider' => $provider, 'token' => $token])
->redirectUrl($redirectUri)
->stateless()
->redirect();
On the callback I get the user based on the token. Using this method allows the third party provider to get access to the JWT token. Which is very unsafe.
My Question(s):
Is there any better way to do this? Should I use some kind of hash + salt + secret?
You should check the JWT.
JSON Web Tokens are an open, industry standard RFC 7519 method for
representing claims securely between two parties.
JWT Token composes of three parts, header, payload and verify signature.
You are using stateless authentication and the only way to authenticate the user is by the JWT Token. To authenticate the user after redirect, you should create a payload containing application's user id, and pass to the third party provider, so that when redirect, they will pass the JWT token back to you.
It is no problem to pass the JWT Token to third party provider, but be aware that the payload should not contain any sensitive data. If the payload is somehow sniffed, it will not have any harm because, if hacker is trying to change the payload, the verify signature helps and the application cannot verify the token and the application will throw exception.
The signature is used to verify that the sender of the JWT is who it
says it is and to ensure that the message wasn't changed along the
way.
I have a Web API and AngularJS client. The API is using default authorization provider given by visual studio to generate the token on token request with grant_type 'password'.
The AngularJS client is able to get the bearer token from Web API by calling the token endpoint with credentials and later passes this token to perform authorized requests in the API.
When AngularJS sends the token on any authorized API call, how is Web API able to validate the token? Where does the token get stored?
I checked in Identity tables in SQL server, I could not find any fields to store this token information. I checked in the configuration file, it is not stored there either. Could you please help me in understanding this concept?
Raj,
By default the token is not stored by the server. Only your client has it and is sending it through the authorization header to the server.
If you used the default template provided by Visual Studio, in the Startup ConfigureAuth method the following IAppBuilder extension is called: app.UseOAuthBearerTokens(OAuthOptions).
This extension coming from the Microsoft.AspNet.Identity.Owin package makes it easy for you to generate and consume tokens, but it is confusing as it is an all in one.
Behind the scene it's using two Owin middlewares:
OAuthAuthorizationServerMiddleware: authorize and deliver tokens
OAuthBearerAuthenticationMiddleware: occurs at the PipelineStage.Authenticate, read the authorization header, check if the token is valid and authenticate the user.
To answer you questions WebAPI is able to validate the token thanks to the OAuthBearerAuthenticationMiddleware, it will ensure that the token sent through the authorization header is valid and not expired. And the token is stored only by your client, if the client loose it, it will have to request a new one.
I advise you to get deeper in the OAuth protocol, and instead of using the extension UseOAuthBearerTokens, take a look at UseOAuthAuthorizationServer and UseOAuthBearerAuthentication, it will help you to better understand how it works.
The generated token will most likely be a JWT (Get Started with JSON Web Tokens), which means it's a self-contained token that is signed with a secret/key that only the server or other trusted parties know.
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.
(emphasis is mine)
This means that when receiving the token the server can ensure that:
the token was originally issued by a trusted party by checking that the signature is valid.
the token is associated with a user that has permissions to perform the following request because the token itself contains information that uniquely identifier that user.
This type of approach has the side-benefit that the server does not need to keep track or store the generated tokens in order to validate them at a later time. Since no one else has the secret/key you can't modify the token without making the signature component invalid, which would then mean a faked token would end up being rejected by the server.
This is a simplified description of what happens, there are much more details around how to issue and validate tokens correctly. You should read the OAuth2 and OpenID Connect specification to learn more on the subject of token-based authentication.
Also note that I assumed a JWT token because it's the format that currently has the most widespread adoption to accomplish scenarios like these ones and it's also the token format to use in conjunction with OAuth2 and OpenID Connect. However, it's still possible to achieve the same with other token formats.
I understand that JWT are stateless tokens that store signed information about the client's claim and are passed to a server via the Authorization HTTP header.
My question is, why do we need JWT when we already have client sessions (https://github.com/mozilla/node-client-sessions)? Client sessions are conceptually the same. They're cookies that contained signed information which when verified means the cookie hasn't been tempered with. Also, client sessions are stored in a cookie and passed via the Cookie HTTP header. It's the same thing only using different words. Am I wrong?
So, why is JWT even around? I could understand that maybe the point is to standardize the way authentication tokens work, but we got along fine without a session ID based standard (each implementation did things their own way). Also, why would the JWT not use cookies as a means of transfer. With cookies, you wouldn't need explicitly send the correct header for every request (simplifying Ajax requests).
Am I missing something?
JWT tokens are signed JSON formatted documents that assert claims about a user (or any principal). If you trust the issuer of the token, you trust the claims in the token and can make authorization decisions based on this.
JWT tokens are often used for calling external Web APIs. These APIs do not necessarily live on the same domain as your website and therefore cannot use the same cookies as your site. JWT tokens are used in REST services as they do not need any session info stored on the server. Using JWT tokens is also not vulnarable to CSRF attacks.
I am developing an API using Codeigniter and Oauth2 (Alex Bilbies library).
The API is being used by my iPhone app. For every request I need to send along the access token as a parameter in the URL. Is there a way to send the token in a header instead? To avoid it getting "exposed"?
Thankful for all input!
OAuth 2.0 bearer tokens allow you to insert them in an HTTP Authorization header as follows:
POST /my/api HTTP/1.1
Host: rs.company.com
Authorization: Bearer abcdef123456
Where abcdef123456 is your Access Token (see: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-bearer-16#section-2.1). In fact the spec says you SHOULD do that in lieu of request parameters if it is possible.
The spec also describes many security considerations when using OAuth 2.0 bearer tokens (see: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-bearer-16#section-4)
Sending an access token over GET is just as insecure as sending it in a header.
OAuth 1 used to get around this with all sorts of encryption, secured passwords, hell you could even turn certifications on. This was all a massive ball-ache, so now in OAuth 2 you just have to use HTTPS which does all of this for you.