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 to setup Django-oauth-toolkit in frontend/backend separated projects? #994

Closed
azataiot opened this issue Jul 10, 2021 · 9 comments
Closed
Labels

Comments

@azataiot
Copy link

I am currently using dj-rest-auth in my project and already set up a nuxt.js & Django project (A). it works perfectly now. But I also want to use Django-OAuth-toolkit to provide introspect connections to my other websites, so that they can log in from my site A.

Firstly, oauth-toolkit as I see is heavily build for django-fullstack, where we build django applications using django templates. Are there any projects which handles the API views for separated frontends like Vue, React ? is any project like this ongoing? (so that I wont have to waste time to start another one.)

For clarification, Site A is a authentication site, where now we have dj-oauth-toolkit installed and working. ( with django- templates and views )

I also have site B, C, D, E, all of those Django sites currently has its own account system, and that is the problem I want to solve using django-oauth toolkit .

Pls anyone with such experience and knowledge commit, it will be really appreciated.

@Andrew-Chen-Wang
Copy link
Member

Andrew-Chen-Wang commented Jul 11, 2021

Fair warning: Excuse me if the tutorials are rat shit because I wrote them with barely any knowledge in the world of OAuth RFCs, not to mention my laziness in the (lack of) actual writing of the tutorial.

Take a look here for a tutorial https://github.com/Andrew-Chen-Wang/django-social-provider-and-consumer-tutorial Guarantee you'll need the Provider section. Depending on how you implement your SPA (if you're doing it like this: https://github.com/Andrew-Chen-Wang/SPA-with-httponly-sessions i.e. use httpOnly cookies like at IG, then use the regular consumer section; if you're doing it with tokens like with drf-SimpleJWT, then use the mobile section with the exception that you still use an http callback, not the custom callback). For most Djangonaughts, they do their consumer authentication through JWTs saved in cookies, so you'll probably follow the mobile consumer route. In which case, if you're going to custom implement the authentication process on your SPA, hit the authorization endpoint with your scopes as query parameters (?scope=A%20B%20C where %20 is a space and A,B,C are scopes IIRC) (ref: my react-native tutorial that complements it)

Just note for SPA users that there are a lot of redirects, so happy debugging :)

PR over at those tutorials (and honestly a good security check) is much appreciated :)

@azataiot
Copy link
Author

Fair warning: Excuse me if the tutorials are rat shit because I wrote them with barely any knowledge in the world of OAuth RFCs, not to mention my laziness in the (lack of) actual writing of the tutorial.

Take a look here for a tutorial https://github.com/Andrew-Chen-Wang/django-social-provider-and-consumer-tutorial Guarantee you'll need the Provider section. Depending on how you implement your SPA (if you're doing it like this: https://github.com/Andrew-Chen-Wang/SPA-with-httponly-sessions i.e. use httpOnly cookies like at IG, then use the regular consumer section; if you're doing it with tokens like with drf-SimpleJWT, then use the mobile section with the exception that you still use an http callback, not the custom callback). For most Djangonaughts, they do their consumer authentication through JWTs saved in cookies, so you'll probably follow the mobile consumer route. In which case, if you're going to custom implement the authentication process on your SPA, hit the authorization endpoint with your scopes as query parameters (?scope=A%20B%20C where %20 is a space and A,B,C are scopes IIRC) (ref: my react-native tutorial that complements it)

Just note for SPA users that there are a lot of redirects, so happy debugging :)

PR over at those tutorials (and honestly a good security check) is much appreciated :)

THANKS FOR YOUR KIND REPLY.

In my application, I use nuxt.js ( a vue.js based framework). And yes, I use a Simple JWT for a token system.
I will read your code and of course if possible I will try to contribute to it.

Thanks again.

@azataiot
Copy link
Author

@Andrew-Chen-Wang I think I am focusing the first problem here:

image


As you said " the provider is a website, not a RESTAPI", In my case, yes it is a REST API. So things started getting complicated.

In my case, the provider ( Django + vue ) itself is a separated system and communicates through json.

@Andrew-Chen-Wang
Copy link
Member

Andrew-Chen-Wang commented Jul 12, 2021

@azataiot Probably makes things easier; you can find lots of the pre-defined configurations I made (like what to actually put into your application registration) in the tutorial (view the Notes section under the provider tutorial if you need more help). Some of the Python code used can be reused as they were from the documentation here, but for actually getting the provider tokens for a DRF context, follow: https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html#step-1-minimal-setup

Note: I'm guessing with the following comment, but I don't think you'll be using SimpleJWT if it's also a provider; SimpleJWT will be used for the provider's own website, but not for the consumer. I think that tutorial will be your new authentication system for third-party websites (i.e. consumers).

I currently don't use SPA for my primary full stack framework due to security issues and a lack of SPA experience, so I placed that assumption there immediately. Sorry for the confusion

@azataiot
Copy link
Author

@Andrew-Chen-Wang
Thanks a lot. I've viewed your code. That's nice organized and comprehensive.

In my current application, I have already finished the registration, login, reset passwords, recover passwords, email, SMS handling, verification and etc (it is now called IAM Service --- which is a Django + Vue application ).

And I want to add functionality to the existing site so that,

  1. Third-party applications and my other applications can use the system I ready-created (IAM) to log in to their application.
  2. In the next step is to complement an SSO on those systems, so that sync login/logout in all the systems.

@Andrew-Chen-Wang
Copy link
Member

@azataiot thanks for taking a look!

For the second point, the SSO is beyond the scope of this package as that actually covers cross-domain. OAuth handles cross-domain, yes, but it accounts for different authentication systems. For example, YouTube.com and Google.com use an SSO, but (if you recall how Django cookies work), they both share the same authentication cookies (ish. They're two separate cookies, but they share the same session keys or at least when one logs out all the other session keys are evicted from their storage; in Django, the default is your SQLite database)

For the first point, what I've mentioned in the above comment is a starting point (assuming it didn't work out for you). Again, I believe your provider should be following the Django OAuth Toolkit documentation for the Django Rest Framework tutorial there. I'm happy to take this conversation over to the other repository so we can figure out a solution together there if need be.

@Andrew-Chen-Wang
Copy link
Member

Andrew-Chen-Wang commented Jul 12, 2021

@azataiot actually, I think the DRF tutorial is all you need for the provider: https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html#step-1-minimal-setup

The problem is the consumer should really never need to enter their user credentials on the provider website. Which is why I dislike the password grant type. Ya know how when you login to YouTube, you get redirected to Google.com? It's (mostly) the same thing that we should be doing here.

That's why I recommend you use this tutorial for your provider: https://github.com/Andrew-Chen-Wang/SPA-with-httponly-sessions It really does make this easier and more secure, but I honestly don't have the experience to be able to guide you on the provider end when it comes to point 1, i.e OAuth, when we take into account security (I dislike the grant type password, especially for a web context).

That's also why I don't merge any SPA related material on SimpleJWT. It gives the wrong message about how we setup safe authentication systems (Instagram doesn't use stateless auth and use Django sessions, and the method is similar if not the same as this tutorial: https://github.com/Andrew-Chen-Wang/SPA-with-httponly-sessions. The only problem with this tutorial is the development platform is iffy to safe the least. Webpack takes a while to reload, but that could be because I have no experience in web pack configuration)

@azataiot
Copy link
Author

@azataiot actually, I think the DRF tutorial is all you need for the provider: https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html#step-1-minimal-setup

It's really about the frontend that you may be confused about

All of the documentation, actually, I've read.

The thins is not clear among us,

just one question :

Where do your user's log in:

  1. users login into the website where the Django project sits ( like this https://github.com/Andrew-Chen-Wang/django-social-provider-and-consumer-tutorial/tree/main/provider ) --- here the frontend is the Django site. login page is rendered by Django using DOT's AuthAuthorizationView(BaseAuthorizationView) then the user gets a code and then exchange the code with a token from DOT's Grant model.
  2. users login to a node js server (Vue.js) --- frontend validates the user data, and Vue sends user data through JSON. ( I do not open anything from the Django side, the Django website is completely API, without any HTTP view.) If you open the Django site in the browser in any circumstances, then that is not my case.

What I did so far :

  1. write REST APIs for authentication/ authorization/ access management. ( all through REST API )
  2. write REST APIs to integrate the existing token system with the DOT's token system.
  3. write REST APIs for registering DOT oAuth2 applications.
  4. write REST APIs for GRANT.

Why I am doing this?

  1. Now in many of my projects, I use Django is just for APIs. I even do not use Django admin and write my own dashboard with JS stuff.
  2. I separate lots of business logic in microservices so that they work better on docker/k8s environments.
  3. All applications are cloud-native -- that is the purpose.
  4. Importantly, again, I do not use Django templates or Django template engine, do not use Django admin.

@Andrew-Chen-Wang I do really wish someone can work and think those with me, I've finished some steps listed above, I just wondering should someone has already done what I am doing, and I am not sure about that.

IF NOT YET, I am also happy to do this with others together, maybe a big PR to the existing DOT or a separate project just focusing on the REST.

@Andrew-Chen-Wang
Copy link
Member

@azataiot I made that tutorial because no one made a decent tutorial with ready-made code with Django templates. I wouldn't expect there to be a good one for SPA, unless my Googling skills are atrocious.

Let's communicate over at Andrew-Chen-Wang/django-social-provider-and-consumer-tutorial#8 so we don't fill up this issue. It'll make it easier for future Googlers to quickly find the tutorial.

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

2 participants