I'm building a single-page web application, fully based on RESTful API. I've seen several topics in that matter, but some things remain unclear for me.
I will need users to log in. Here are some of my ideas:
I can send e-mail and password to API and use basic auth. I'm not sure where should I keep password, should it be encrypted and if so: how?
Can I use built-in session system instead? Is it wrong to use cookies directly in the RESTful API? Why is it so popular to send credentials/keys to API itself instead of using cookies?
I thought about having one API key per user, return it in login action and keep it in localStorage. I guess it's not the greatest idea to have just one key per user?
Then, I came up with idea to have separate keys table and add random keys each time somebody logs in. On logout, the key would go away and no longer be valid. This is more secure than previous idea.
How is it solved in simple projects? I'd like to make it simple but not ridiculously inserure.
Please help.
The commonly approach is to use the header Authorization in REST. The state of the application must be on the client side with REST and shouldn'a be tied to a particularly client kind (browser with cookies)
I think that this link could be helpful:
Implementing authentication with tokens for RESTful applications : https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
There is also à great question to à similar question here : https://softwareengineering.stackexchange.com/questions/141019/should-cookies-be-used-in-a-restful-api
Hope it helps,
Thierry
Related
I have a JSON REST API written in Symfony 2.7, and I want to authenticate & authorize users. This is my first time doing this, so I have some doubts/questions.
For that, I thought several methods:
User & password, and then save a session in the back end
Same as 1), but add an "apiToken" (randomly generate when user register) and then sending back & forth the apiToken in every single request to check user identity.
Use OAuth (which I'm currently reading about it).
I read that using OAuth for a simple API is like an "overkill", but on the safe side it sticks to standards and also allows me to use it when using my API with mobile devices and different platforms.
Also, I don't know too much about security flaws of using method 1) or 2).
I know this is maybe based on opinions, but I don't know any other site to post this question, as Symfony official mailing was shut down and migrate here it seems.
As you seems to know, your question is too opinion based.
If I can give you some advices (too long for a 600chars comment),
OAuth is powerful, but so much free.
I mean that you can easily implement it sort as everything works well while having a set of potential security issues without being aware of their existence.
Libraries and bundles providing OAuth are hard to maintain because of the new security issues regularly found.
On the other hand, if you need the benefits of OAuth (be a client and/or a server, compatible with the most part of social networks), go learn OAuth and do your experience with it.
Otherwise, use a simple credentials/request token two-step authentication.
See the JWT Authentication tutorial by KnpLabs,
Symfony Guard Authentication by Ryan Weaver,
and the great LexikJWTAuthenticationBundle, easy to implement and to use.
I'm struggling with an issue here. I've searched repeatedly for answers, but have been unable to find the exact answer I'm looking for. I'm attempting to build a secure authentication method for a REST api. My question is, how do we handle a login for a REST api?
Since a REST api is meant to be stateless every time, does that mean we need to store the client's username/password on the client's end (perhaps hashed), and send it in with every request? I'd be much more comfortable using a system like authentication tokens that are created upon logging in the first time, but does that go against the basic rules of REST, since this technically creates a "state" on the server?
What is the best and most practical method to handle this? As I wrote earlier, I'm struggling to come up with an answer to this; maybe that is due to this problem not having a clear answer, but I honestly don't know.
Thanks in advance.
That's also my understanding of REST: clients send login/password to the server along with every request. The server has to authenticate the client based on this information only. With regard to the Hypermedia principle of REST, having a user logged in is not an application state, in my understanding.
Is it possible to use Smartsheet's API to sign into Smartsheet on the Web. I am thinking of creating a form-based auth that uses the API to login. Has anyone done something like this? or is this even possible with the tokens that can be produced by the API. I am aiming for a web based single sign on without using SAML.
I'm not totally clear on what you are asking, so I'll address each question individually in hopes that it addresses your overall question:
Is it possible to use Smartsheet's API to sign into Smartsheet on the Web?
No, you cannot create a web session using the api. For 3rd party apps, that would defeat the purpose of using OAuth2 since the whole goal with OAuth is to grant limited access to protected resources. For user-generated access tokens, it could be feasible, since those tokens have unrestricted access, but the API does not currently support that.
I am thinking of creating a form-based auth that uses the API to login. Has anyone done something like this?
I assume you mean you will create a form to collect a user's Smartsheet credentials and use those to have an SSO experience into Smartsheet? This is technically possible, but I'd strongly discourage against it. To create an SSO experience, you'd need to retain the password in a way that allows you to POST it on behalf of the user. This means you'd store it in a 2-way encrypted state (at best), which is definitely not best practice. Again, I'd highly recommend NOT doing this.
I am aiming for a web based single sign on without using SAML.
If you want an SSO experience into Smartsheet, you can either use SAML or Google (not truly SSO, but pretty close). There isn't an API-based approach currently.
Side note, if you want to go the other way, meaning you have a website and you want to use Smartsheet (or any OAuth2-based API for that matter) as the identity provider, you could use the 3rd Party OAuth2 flow. See the docs here. You could then add a "Login with Smartsheet" button to initiate that flow, much like we see everywhere on the web with "Login with Google" or "Login with Facebook".
Hi I was looking at flask-login at handles the session login nicely, this work good for templating and views where I have access to the session.
Nevertheless I have been trying to know if there is a way I can send a user_token to authorized a call. I looked at the documentstion and is very vague regarding this. It said that I should
Implement get_auth_token in my User object.
Decorte a #user_loader function that can load the user token base.
I have though seen the following (please correct me If I am wrong)
Cookie base to store the auth token is there a way I can decide to send the token as part of the parameters, body or in the headers insteado having to get it from the cookie.
I am not quite sure how to authenticate a call with auth token.
I got a Way better approach that fits better my needs. Basically I extends LoginManager pretty easy and straighfoward if you take a look at the source of flask-plugin you come to realize that there is a call that is made #before_request there is a method called reload_user, this is the what I end up doing
class CustomLoginManager(LoginManager):
def reload_user(self):
if request.headers.has_key('Authorization'):
ctx = _request_ctx_stack.top
ctx.user = User.get(token=request.headers['Authorization'])
return
super(CustomLoginManager,self).reload_user()
If in my header I pass an authorization key then I will try to load using this key instead of session based approach, of course I am going to need to add more security layer to this approach proably by signing the key but overall this was what I needed.
Thanks all.
BTW you can override a bunch of others method and I highly recomend to take a look at the plugin source, so you can understand more deeply what it does 644 lines of codes worth reading
https://github.com/maxcountryman/flask-login/blob/master/flask_login.py
It seems like you're wanting something like OAuth instead of using Flask-Login. In case you don't know (quoted from Wikipedia), OAuth is a protocol that utilizes tokens in order to access resources on behalf of a resource owner. Think giving a user the ability to give out a valet key to certain portions of your site. Many sites, such as Google, Facebook, and Twitter use OAuth for authenticating third party clients in order to access certain user resources.
Right now, there's a split between the less flexible and less complex OAuth 1.0a and the more flexible but more complex OAuth 2.0. Many libraries exist for OAuth 1.0a in Python, but fewer for OAuth 2.0. However, there is a selection of those for OAuth 2.0 if stability isn't a top concern right now.
For the client, Flask-OAuth is available if you're going with OAuth 1.0a, and it is maintained by Armin, the Flask creator itself, so you can feel assured that it won't die. For the provider, there's an extension called Flask-OAuthProvider with OAuth 1.0a support. If you don't mind integrating it yourself and want 2.0 support, pyoauth2 provides you with both a client and a provider, though it looks less maintained.
Hopefully this helps you with exploring one possible avenue to utilize auth tokens, albeit without using Flask-Login. In my opinion, one shouldn't re-implement a protocol unless they understand it, so I recommend reading up about OAuth even if you decide not to use it. Many great articles exist on it, such as this article from Google and this one, too.
Just as an update, Flask-Login now has a 'header_loader' function, which can be used in conjunction with the standard 'user_loader'. Taken directly from the docs:
#login_manager.header_loader
def load_user_from_header(header_val):
if header_val.startswith('Basic '):
header_val = header_val.replace('Basic ', '', 1)
try:
header_val = base64.b64decode(header_val)
except TypeError:
pass
return User.query.filter_by(api_key=header_val).first()
Here's the link to the section in the Flask-Login docs
Which are the steps must I follow to implement a token authentication in my web page?
Any summary or links will be appreciated.
I want to implement similar to Facebook or Google, first time client loggin and receive token and then use it in next actions.
I read also about OAuth but I don't want to give access to my application from 3rd party.
Thanks for the long response and it seems clear to me I need to read more about this.
What I want is to know the "steps" to implement a basic web application that uses token authentication. That is user logging once and then can make some actions: add content, edit, etc.
I know what I'm saying is similar to a session, where server adds a SESSION_ID on the HTML header and later request are identified and associated with that session. I read sessions way isn't good to scale so I want to implement a similar system like gmail or facebook before they go to OAuth. Probably I'm talking about something similar to oauth (i don't read in much depth) but witj two-legged instead three-legged.
You should think about your requirements, pick an appropriate protocol and some decent piece of software that implements it.
It's really hard to say more without more details:
are you talking about authentication for one or for multiple web applications? do you need single sign on between different web applications?
should all user data be stored on your server or should user be able to login e.g. with the google account?
should the token contain informations about the user?
on what platform are your applications developed?
what authentication method should be used?
do you want to realize a portal?
There is a really wide range of protocols and tools which might or might not fit to your requirements:
http://en.wikipedia.org/wiki/Category:Authentication_methods
http://en.wikipedia.org/wiki/Category:Identity_management_systems
I personally like CAS ( http://www.jasig.org/cas) for token-base SSO between multiple web applications. It's Java based but also has some support for PHP and .Net.
OpenID is fine, if you want to allow users to login with their Google, Yahoo, whatever account (configurable...) and don't want to store user information by yourself.
Kerberos/SPNEGO is the way to go if you want to haven integrated windows-sso for your corporate intranet applications.
For university applications SAML/Shibboleth probably is best. Outside universities it's somewhat less popular, probably cause it's a fairly complex protocol.
Oh and I almost forget: Most of the web frameworks/standards have there own version of plain-old "form based authentication". Where a user goes to a login form enters its username and password. Both are with or without SSL transported to the web/application server. The server validates it against some kind of database and gives a cookie to the user, which is transmitted and validated every time the user sends a request. But beside all this shiny protocols this seems to be pretty boring :-)
And before doing anything with web authentication, you might think for a moment about web security in general ( http://journal.paul.querna.org/articles/2010/04/11/internet-security-is-a-failure/ http://www.eff.org/files/DefconSSLiverse.pdf) and what you can do to not make it even worse on your site ( http://www.codinghorror.com/blog/2008/08/protecting-your-cookies-httponly.html http://owasptop10.googlecode.com/files/OWASP%20Top%2010%20-%202010.pdf).
see your point.
On the protocol level a very simplistic token approach is HTTP Basic Authentication. But this often doesn't fit, as there is no logout function etc.
A custom, simple cookie based approach can for example look like this:
The server generates some kind of secret (a value that is hard to guess)
When a user tries to access a protected resource, he is redirected to a login form
after successful authentication he gets a cookie. This cookie contains three values: username, timestamp and a hash of {username server-secret timestamp}.
with every user request the server recalculates the hash values and compares it to the value which the client sends in its cookie
(needs more consideration of: httponly and secure flag, transport layer security, replay attacks etc)
Amazon S3 stores its authentication token in an HTTP Header and uses HMAC for calculating it. It's described here: http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?S3_Authentication.html (Not necessarily recommended for using with a browser based web application)
If there is a book about REST anywhere near you, you may look if it has a chapter about authentication. Probably things are much nicer explained there than here :-)
There are some frameworks which are capable of doing this kind of authentication. For security reasons it would make sense to check them first before implementing your own stuff.