My app is using Angular2 for the front-end, served by a separate (cross domain) backend server running express and using passport.js for Google Oauth authentication.
When a user is authenticated by the server using Passport (through google oauth), their user data is loaded from the database and included in the credentials, which is used to determine which backend API routes they are authorized to use. (It's based off this tutorial on scotch.io that I'm sure everyone has seen: https://scotch.io/tutorials/easy-node-authentication-setup-and-local )
I want to access this user object in my front-end as well to enable route-guards that depend on a user's access level (defined in their user object on the server).
From this question it seems the data is sent via a JWT and is readable on the front-end, just not changeable, which is fine: https://www.reddit.com/r/Angular2/comments/4ud0ac/ng2_secure_connection_front_to_back/
How do I access and read that token on the client? All I can find is the 'connect.sid' session cookie set by express. The payload of the cookie doesn't fit a standard JWT as it only has 2 sections, not 3.
You are probably not using JWT but cookie-based sessions if you followed the tutorial. The cookie only contains a session ID which your server uses to identify the session from the session store, and using this information you probably dig up something from the database in deserializeUser. That is then available to you in req.user in the backend.
You could of course add the user data to the response of every request but if you really are using cookie-based sessions sending the user object with every response likely makes little sense. You could eg. just add a route that will return the relevant parts of req.user:
app.get('/users', function(req, res) {
res.json({ username : req.user.username });
);
Related
I am creating api using cakePHP. I have created an api for user log in. This log in functionality is working fine.
Here is the log in function -
public function login(){
if ($this->request->is('post')) {
$user = $this->Auth->identify();
}
}
Now, the I am facing problem is, how I can test from other api that is the user is logged in or not? In web application it can be done by default auth system ($this->Auth->user()). But I am not getting how I can check is this user logged in or not from another api. Do I need to send api parameter to each api request ? or any other suggestion ?
Note : I can't send any token in header. Because in header I am sending jwt token. Because in my application there are two kind of authentication. One is log in or not? and another one is depending some other input from user. That is handling by jwt. So jwt token I am already sending by header. So header is already used.
A couple of things to clarify.
In a regular app, the user logs in with a post request and on successful authentication a session is created. This session is a bit of information that the user supplies in each of the following requests and the server then recognises the user. This accomplished by the Auth component in it's default settings.
In an API you could do the same: the user logs in, receives the session and attaches the session cookie-like object on each following requests. (Example of such a Python client.) However, this is not considered good practice as APIs should be stateless (so without requiring something like cookies). The solution of working with tokens, for instance hashes of some secret token together with a timestamp. The Auth component also supports this pretty well. After setting it up, you can simply call $this->Auth->user(), like you would normally and it returns either false or an array of user information. See link below.
Note that by default this authentication type will block unauthenticated users, so you will never see ->user() return false unless you make pages as public.
See also:
(Cookbook > Authentication > Creating stateless authentication systems)
I have a Vuejs application created using Nuxtjs. I am also using Django as the backend server, and I made an API to interact with the backend server (Django) and front-end app (Vuejs/Nuxtjs). And any API related fetch are done in the AsyncData function of the page to render the data on the server-side using axios. Also, I am using json web token authentication, and the API generates a jwt token after successful login which is stored in the cookie. So on the backend, it will always check for the request's authorization header for the token. If the request is from a logged in user (authorized token) then return authenticated json data, or else return non authenticated data.
The problem:
When the user navigates to the app, I would like to check if the user is authenticated. If the user is authenticated, render the authenticated page. If not then display non authenticated page.
My thoughts:
When the fetch is done from the App on the AsyncData function, I would check whether there is any value for the cookie. If there is then send the token with the request's authorization header. But, since the page will be rendered on the server first, and not on the client side (where the cookie actually is) it will never find the token for the authorization.
How can I check if the user is already logged in or not so that I can get authenticated and non authenticated data respectively from the API?
Update
When I successfully log in (post authorized email and password), I get a json response back with the token, which I set in the cookie like this:
this.$cookie.set('my_auth_token', this.token, {expires: 15})
How can I retrieve client side cookie and into the nuxt server for server side rendering?
Cookies are exposed in the (Express) Nuxt server through middleware.
Specifically, they can be read from the req.headers.cookie property. You can see an example implementation of this in the Nuxt documentation.
Regarding your implementation: fetching the privileged data from your API using Node would seem to be the ideal way to delegate session handling to that single service (rather than both) and provide SSR for your users.
If you've chosen to instead implement your session handling on the Django service then you'll need to "forward" your cookies by passing them into your axios request headers.
I did something similar using Firebase authentication. There is an example project on Github as well as a blog entry outlining the important files and configuration used in the application.
I have Firebase authentication set up on the client side, and on the server side I can take a JWT token and decode the account ID. But how does this work when I want each page load to be authenticated on the server before the page is generated?
On login or each page load, can I simply store the last JWT token into cookies so that I can read them on my server? Aside from that, I don't know how else for my server to get that information aside from each link being an AJAX call.
This seems to be the only way to do it presuming you're using the firebase auth library to decode and verify the tokens on the server and not some kind of JWT parsing library.
Firebase admin includes methods for decoding and verifying id tokens and extrapolating all the information. This prevents cookie forgery and keeps firebase auth as your single source of truth for whether or not a user is authenticated.
for example (in node):
const admin = require("firebase-admin");
admin.initalizeApp({
credential: admin.credential.cert(yourServiceAccountJsonHere),
databaseURL: "http://YOURDATABASE.firebaseio.com/"
});
admin.verifyIdToken("usertokenasastring") //returns a promise
.then(function(decodedToken){
//process the decoded user token somehow
});
Firebase makes a call to your database, and makes sure that that user is logged in and that all the other information in the JWT makes sense, so you don't have to worry about implementing any kind of verification server side.
I'm trying to figure out how is best to do authentication and login flow with Ember. I'll also add that this is the first web app I've built so it's all a bit new to me.
I have an Express.js backend with protected endpoints using JWTs (I'm using Passport, express-jwt and jsonwebtoken for that) and that all works.
On the client-side, I'm using Ember
Simple Auth with the JWT authenticator. I have the login flow working (I'm using the login-controller-mixin) and correctly see the isAuthenticated flag in the inspector after a successful login.
The thing I'm struggling with is what to do after login: once a user logs in and gets the token, should I make a subsequent call to get the user details, e.g. GET /me, so that I can then have a representative user model client side? These details would then let me transition to the appropriate route.
See this example in the repo for an example of how to add a property to the session that provides access to the current user.
I have this scenario: a corporate site (MVC 4) and a web shop; add OAuth 2 SSO functionality. Both sites have their own members, but the corp site (for which I'm responsible) must also work as an OAuth 2 authorization server and will store a web shop user id for each member. The shop requested the following endpoints:
Auth endpoint
• authorization:
…/oauth2/authorize?client_id={CLIENT_ID}&state={STATE}&response_type=code&redirect_uri={REDIRECT_URI}
• token
…/oauth2/token?code={TOKEN}&client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&redirect_uri={REDIRECT_URI}&grant_type=authorization_code
…/oauth2/token?refresh_token={TOKEN}&client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&redirect_uri={REDIRECT_URI}&grant_type=refresh_token
API endpoint
• getid (will return JSON with the shop id of the member):
…/oauth2/api/getid?access_token={TOKEN}
I don't have experience with OAuth, so I was looking at the DotNetOpenAuth samples and have concluded that I need to implement an OAuthAuthorizationServer, but modifying the sample to fit my requirements is difficult as it seems to do more and is complex.
As researching DotNetOpenAuth seems to be so time consuming, I'd like to ask: is modifying the OAuthAuthorizationServer sample the right approach? Or should I try to make a native implementation or try a different OAuth library that may be easier to use in my situation?
Please comment on my overall plan:
-keep the corp site member login flow standard forms auth, straightforward LogOn controller
-add an OAuth controller that will implement the three required endpoints as actions
-when the authorization action is reached, I validate the client and redirect to LogOn passing on the redirect_uri; I think the Authorize ActionResult from OAuthController.cs from the sample is where I should start investigating this, and return an AccountAuthorizeModel. Is this correct?
-after the user logs in, and if the login page was reached from the authorization endpoint, I redirect to redirect_uri with the code attached; I don't know where to start with this one. PrepareApproveAuthorizationRequest then PrepareResponse? Where does the code come from? Where in the flow should I add a new ClientAuthorization in the database?
-the shop will then use the code to get or refresh the token, from the /token endpoint; simply return HandleTokenRequest?
-with the token the shop site will be able to get the member data JSON; have to find out how to validate the token
Now, besides adding a Clients table to store the client ids and secrets, and ClientAuthorization to keep track of who's authorized, I don't know if the other tables from the DotNetOpenAuth sample are used and when: Nonce, SymmetricCryptoKey, User.
Modifying OAuth2AuthorizationServer.cs seems straightforward, I only have to add real certificates and make sure the clients are pulled from my data context.
Thanks!
I think you are right in most of the points. Let's comment them:
OAuth server should have 2 endpoints (not 3), as requesting token and refreshing token goes to the same endpoint (TokenEndpoint).
It depends if your are going to implement a different authentication server (or controller), or you are going to implement the authentication responsibility inside the authorization server. In case they are separated, the authentication server should be the one responsible of displaying the logon, authenticate and communicate with authorization server using OpenID protocol (Also supported by DotNetOpenAuth).
Once the user is authenticated, the authorization server should store the data of the user identity somehow, and return the authorization code (if using this Oauth flow) using DotNetOpenAuth functions:
var response =
this.AuthServer.PrepareApproveAuthorizationRequest(AuthorizationRequest,
User.Identity.Name);
return this.AuthServer.Channel.PrepareResponse(response);
finalResponse.AsActionResult();
I don't think you need to save nothing about the authorization process in the database, and the code is generated by DotNetOpenAuth and sent to the client into the query string of the redirection.
Then, the client should get the code (ProcessUserAuthorization) and call the TokenEndpoint. This endpoint is just returning HandleTokenRequest, that internally is calling to some OAuthAuthorizationServer functions, such as CreateAccessToken.
Once the client has the access token, it should call the resources, sending the token into the HTTP Header 'Authorization'. The resource server is the responsible to validate the token.
var resourceServer = new ResourceServer(new
StandardAccessTokenAnalyzer(signing, encrypting));
AccessToken token = resourceServer.GetAccessToken(request, scopes);
A store provider for nonce and crytoKeys is needed using this flow. Have a look to class InMemoryCryptoKeyStore in:
https://github.com/DotNetOpenAuth/DotNetOpenAuth/wiki/Security-scenarios
Hope this helps!