From the posts about REST services, I see that it should not be used sessions together with REST, and with every request there is need to send user credentials to the REST service. But I don't see that somebody continues then how to make the authorization in next requests after login.
In my project, I authenticate (login) the user, checking his credentials from database server.
If with every REST request also comes user credentials again, does this mean that, for any need of authorization after login, I need to check the credentials again from the database?
This means, after login, with almost every click and surfing pages, I need to access to the database to check the user credentials, just like I do it for login.
Or...
Am I missing some thing?
Is there another way to remember in the server side that the user had already logged in before and thus is authorised?
Do I keep some secret key related to the user in the server, and then check this etc.? But, does not this mean keeping a session?
REST => Not Session => Send credentials with every request
Does the above mean, => Authorize the user just like in the authentication ?
Or what are other alternatives?
Thank you for clarifications.
I think that this is the best approach:
REST => Not Session => Send credentials with every request
Take a look on OAuth. The version 1.0 may be useful for you.
Spring Security already have implementations for OAuth in Java.
If with every REST request also comes user credentials again, does this mean that, for any need of authorization after login, I need to check the credentials again from the database?
You have to authenticate user on each request, but whether authentication uses database or not depends on implementation. By the way, you also have to then authorize the request for the authenticated user.
Do I keep some secret key related to the user in the server, and then check this etc.? But, does not this mean keeping a session?
You can have some secret key known only to the user as an alternative to username-password pair and use this secret key for authentication.
The presence of a secret key doesn't mean keeping a session, because it is not necessarily change on a per session basis.
In my project, I authenticate (login) the user, checking his credentials from database server.
Login is not authentication, it's usually a request for a secret key / session key done using username-password pair for authentication
Related
I want to build a webapp that uses the wallet address as account, but yet I want to store the user in my db to allow specifying a nickname.
The problem I'm dealing with is that I want to call different apis, where the user needs to be authenticated / authorized in order to gain access .
Since the authentication happens 100% client side in my case (through the tronlink extension and TronWeb), I don't see another way as to add supplementary authentication for my webapp specifically.
If the user logs in to my app with a different password (not using the private key of the wallet), it seems like bad user experience as the user needs to authenticate twice (through Tronweb AND my webapp with a password).
How do you solve this problem?
It seems that the way to handle this is to foresee a separate login flow for the web app after all.
Even when the user already has logged in into Tronlink, it needs to obtain a token to authenticate rest calls.
The way it would appear to work is by generating a random nonce and storing this nonce along with the public key in the User table.
The login flow then consists of signing the nonce in the front-end, and verifying the signature in the backend after which the token will be generated and returned.
I have created a website which allows the user to authenticate against oauth2 (from another provider), the basic flow is (assuming a new user):
The user loads my webpage
An OAuth request token key and secret is provided by the OAuth endpoint
I store the request token into the user's cookies
The user is redirected to the OAuth authentication page from an external provider
The user accepts and is redirected by to my webpage with URL parameters which specify the OAuth verifier and OAuth token
Using the request token (retrieved from cookies) and OAuth verifier (passed via URL parameters), I am able to get an access token key and secret from the OAuth endpoint.
I am now able to authenticate with the providers API and use that to get the logged in user ID.
I then store into a MySQL database, the user ID, a token which I generate as a random unsigned integer, OAuth token and OAuth secret. In cases of the token I generate already being in the database, I just continue in a loop until a unique token is generated. The MySQL database has a strong name, username and password. The database user can only access the table in question and only has privileges to add an entry, delete an entry and make a query.
I clear the request token from the user's cookies and instead store the user ID and my generated token.
When a user comes back to my website, I check if they have the user ID and token stored in their cookies, if so I attempt to look up the OAuth token and secret from MySQL. If they are found, I test they are still valid (does the API endpoint accept them) and if so, the user remains 'logged in' to my website. In cases where the user ID or token isn't found in MySQL or cases where it is found, but is not accepted by the endpoint (expired?), I just go back through the flow above.
The above all works correctly, new users can successfully authenticate, returning users find the website remembers them. I do not expose the OAuth token key or secret to the user and instead, give the user this token ID which I generate.
Are there any problems with what I am doing?
Should I be encrypting the OAuth token key and secret in my database?
Is there a problem with the fact if someone was to gain access to the token I generate, along with the user ID, they would be able to call my scripts. Is this a problem?
Should I be encrypting the user ID and token I generate before storing it in the user's cookies? Taking into account, ultimately whatever is stored in the user's cookies will get passed to my script, so if I were to encrypt, store to cookies, then next time read from cookies and decrypt, the user would still be able to access my endpoints by simply passing the encrypted version (assuming the server decrypts, if the client decrypts then the decryption key would be accessible via the users browser anyway), which doesn't immediately appear to offer any further security.
My goal is to tighten up the steps above so it is deemed robust and secure. The actual use case for my web site means it'll only have a tiny number of users (if any) using it. It was more of a learning process for me, combined with implementing something I actually need. But for the learning aspect alone, I would like to make everything sensible and secure. I am not trying to be overly pedantic and implement steps no other similar websites would implement, basically I would like my site to be secure enough that if there ever was a problem, no one could point a finger at me and say I didn't implement an adequate security system.
I'm using Django REST framework JWT library for authentication in my django application. And I thought the whole idea of using JSON Web Token Authentication was NOT having a database trip in every request.
But it still retrieves user's data (which is stored in the token's PAYLOAD) from database per request.
What am I doing wrong?
The webtoken mechanism and the server authentication internals are rather orthogonal.
The web token just allows the holder to say who they are. It is similar to holding a user's username and password, except the token can be revoked without the user having to learn a new password. This authentication technique has nothing to do with whether the server will do a database access.
If you wish to eliminate a DB access during authentication on the server, you can use some sort of authentication caching mechanism like django-cached_authentication_middleware.
I have two servers.
Server A - this is whole bussines logic and API for mobile application.
Server B - in simply words, this is a webpage.
And now, I need to authenticate user on B but, by the 'user-data' from A.
E.G.
On A server I have user with loggin/password. And I need to use this same login/password on B server. There is some nice solution for that? Or just use tokens?
Presumed that you have an authentication mechanism in your server A.
You have to use your server A as an Identity provider. Request to your B-server should have a session header. If this session is not valid in B-server then you have to ask for credential from the web user and forward this request to your Identity Provider(Server-A). If Server-A can identify the given credential, initiate a session in server-B for this user for a particular time frame. You have to manage this session in the Server-B.
When this user logged out from server-B just destroy the session.
tokens should be fine such as a bearer token on the Authorization header. There are different strategies such as opaque tokens vs JWTs, etc.
I actually did a write up on API authentication tutorial and security holes:
https://www.moesif.com/blog/technical/restful-apis/Authorization-on-RESTful-APIs/
I am building a app/API that allows user to login with Facebook, Twitter or Google. I am wondering what are the best practices in allowing those user to use the same account to login to the API.
A couple Ideas that I have had is pass the auth token/cookie in a header to the API for every request and use that to authenticate on the backend.
Run my own OAuth setup and make the user authenticate once with the back end to get my OAuth token and use those from then on.
I am doing the same thing and my solution is to match the email addresses that you get from these respective APIs.
For Facebook, you need special permission from the end user to get the email address registered there. You do this by adding &scope=email to the first oauth request.
A disadvantage is that you need to get this permission from the end user and they may decline. Another disadvantage is that users need to use the same email addresses for Google, Facebook and Twitter.
An advantage is that user records are merged automatically, so users can directly access all their data if they logged in the first time through Google, and the second time through Facebook.
Another approach would be to manually merge their data by making them log in to Google when they are already logged in through Facebook. Then you can conclude that they are the same user, even when they use different email addresses for both. But this is a more tedious approach, as you still need to merge the app's user data from both accounts.
Your first solution is exactly the way I do it. As all my rest services are stateless, the access token goes in the header and is parsed by spring security authentication filters on every request. I use a grails sever with the spring-security-oauth plugin. We also run a website which allows for using session cookies for browser based access.