Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How does it work? #58

Closed
BenDevelopment opened this issue May 1, 2017 · 18 comments
Closed

How does it work? #58

BenDevelopment opened this issue May 1, 2017 · 18 comments
Labels

Comments

@BenDevelopment
Copy link

BenDevelopment commented May 1, 2017

Can someone provide a short example or tutorial to explain how knox works? I have a DRF backend app and many client (web, ios, android). I would like to add some imprivment to my backend to allow the user to have a different token by client.
But when I try to login trough api/auth/login/ endpoint, I got a error 401.
When I look at the code, the LoginView need the user to be logged in. How is it possible to be logged in in the LoginView (that doesn't makes sens for me ^^)?

Thank you for your help!

@belugame
Copy link
Collaborator

belugame commented May 2, 2017

How do you try to login? I suspect a config issue.

Have a look at the docs, LoginView is explained quite detailed:
https://james1345.github.io/django-rest-knox/views/

rest-knox will only give tokens to users that are authenticated. Simply because if you have a token you no longer need to access the LoginView. And if you don't have a token, rest-knox does not know who you are. You need password and username to receive a token.

To make your user authenticated, you can e.g. use a form that creates a django session or BasicAuth where you send the credentials per post request. But don't try to send a token to knox's LoginView.

e.g. with httpie http -ja user@domain.com:secretpassword POST myhost.com/api/auth/login/

On success, you will receive a token that you then use for any following request.

Django provides views for authenticating via a form out of the box. See last code box under this caption:
https://docs.djangoproject.com/en/1.11/topics/auth/default/#the-login-required-decorator

Hope that clears up your misunderstanding.

@belugame belugame changed the title How does it works ? How does it work? May 2, 2017
@BenDevelopment
Copy link
Author

Mmhh maybe I don't get how Knox works. I'm currently using django-rest-auth with all-auth.

My current workflow is:

  • User post login and password.
  • Server check if login and password are ok, then returns a token.
  • The user send requests from client passing this token to http header so the server can identificate the user and return datas.
  • If the user try to login in another client, the server returns the existing token.
  • If the user log out from a client, the token is deleted from the server so the user is disconected from all clients (since the token is no longer valid).

What should be the Knox' workflow?

@belugame
Copy link
Collaborator

belugame commented May 2, 2017

Starting from your 3rd bullet point rest-knox will act differently. It will create a new token and not return the existing one. You can look at the tests to see how it behaves: https://github.com/James1345/django-rest-knox/blob/master/tests/tests.py#L20

@BenDevelopment
Copy link
Author

Ok thank you for your reply. I think you're right, the 401 error should be caused by a setting issue. I will try to find this issue and come back here to give more informations.

@belugame belugame closed this as completed May 4, 2017
@alrhalford
Copy link

This thread is really helpful, but just a quick follow-up: If I need to authenticate the user through some method that takes username and password (as described by @BenDevelopment), what does the Knox LoginView actually do?

@johnraz
Copy link
Collaborator

johnraz commented Apr 1, 2019

Hi!
Could you be a bit more specific maybe? because the login view does various things and if you want to know it all, I would advise you to read the code (😉), if you have a specific question I would gladly answer.
Cheers!

@alrhalford
Copy link

Hi, absolutely, sorry. The view that knox calls the "LoginView". I've read the code, and I see that amongst other things, it provides an auth token. My question, basically, is that since I apparently need to already have an auth token to access the view, what is the point of this view? In what sense does it actually Log me in, since I already have a token?

I hope I've explained that a bit more clearly. I really appreciate your responsiveness!

@johnraz
Copy link
Collaborator

johnraz commented Apr 1, 2019

Ah no problem, well it's true that one is confusing.
The view is using the DEFAULT_AUTHENTICATION_CLASSES which I believe depends on your DRF settings: https://github.com/James1345/django-rest-knox/blob/707f6980d831f79416a1b4ed47fbd7fb24e76180/knox/views.py#L14-L16

So if you setup, say, basic-auth in the default authentication class, you would be able to authenticate to that view via basic-auth.

If you look at the logout view, it's using the TokenAuthentication only so it won't work with basic-auth but only with the token:
https://github.com/James1345/django-rest-knox/blob/707f6980d831f79416a1b4ed47fbd7fb24e76180/knox/views.py#L58-L60

I hope this clarifies things 😉

@belugame
Copy link
Collaborator

belugame commented Apr 1, 2019

I still find it confusing myself, each time relearning it :D

@alrhalford
Copy link

Ah, that makes much more sense. So I should restrict the login view to Basic Auth, and then all other views to Token Auth, using the token obtained by the login view?

@johnraz
Copy link
Collaborator

johnraz commented Apr 1, 2019

Exactly, yes 👍🏻

@alrhalford
Copy link

Thank you so much for your help, and patience!

@clintonb
Copy link

This information should be in the documentation. I'm used to OAuth, and this is my first time using token authentication. Based on the documentation as written, I believed I could POST username and password to the login end point to get a token.

This is not the case. I still need a login page of some sort (seemingly server-side), and the session generated from that login is exchanged for a token. This seems unnecessarily complicated; although, I admit I could be missing something from a security perspective.

@johnraz
Copy link
Collaborator

johnraz commented Nov 17, 2019

@clintonb feel free to contribute to the docs. Also the login view is provided for you, and you can just issue a POST to it with the proper headers, as I explained above it’s using DRF’s authentication settings. Not sure what you mean by needing a login page... if you want to log users in, you need a login page... right?

@clintonb
Copy link

@johnraz thanks. The error was on my end. My urls.py was sending the login requests to my catch-all view for React. It's all working now.

Docs PR is forthcoming.

@johnraz
Copy link
Collaborator

johnraz commented Nov 17, 2019

Also as you mentioned react, I thought I would also strongly advise against storing any token client side on a web application but use a more traditional cookie based session, auth0’s documentation is pretty clear about it:

https://auth0.com/docs/security/store-tokens#don-t-store-tokens-in-local-storage

and this article is a bit more opiniated but draws a good picture of why you shouldn’t store anything like a secret anywhere else than in an HTTP only cookie:

https://dev.to/rdegges/please-stop-using-local-storage-1i04

and finally owasp’s words:
https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#local-storage

cheers

@clintonb
Copy link

@johnraz thanks for the info. Given this info, does it make sense to use token-based authentication at all for web clients? I'm getting the sense that I should stick with SessionAuthentication for the web client and worry about tokens solely for external/mobile clients.

Soapbox: This is all a bit confusing since nearly every blog post/tutorial on integrating DRF and React makes use of local storage. This is one of the reasons I don't enjoy frontend development.

@johnraz
Copy link
Collaborator

johnraz commented Nov 17, 2019

I use session auth for my web frontend - all the time unless I really dont care about security which really never happened 😂 I was also amazed at how misleading online resources are on the subject... Mobile and server to server communication are indeed the right candidate for token based auth.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants