We're working on a project that depends on PSA (0.2.1) for authentications with google oauth2 (offline). Somehow we lost some refresh tokens of some users, we want to force those users to RE-AUTHENTICATE so we can get new refresh token from google
we tried both :
Diconnect those users using /diconnect/google-oauth2, we got a NotAllowedToDisconnect exception, even after removing social.pipeline.disconnect.allowed_to_disconnect from SOCIAL_AUTH_DISCONNECT_PIPELINE, we got no exception, but when the user re-authenticate, there is no refreh_token in google response
add approval_prompt=force to 'account:social:begin' url, but it doesn't return the refresh_token
Any idea will be highly appreciated.
Update: We tried to use {% url 'account:social:begin' 'google-oauth2' %}?approval_prompt=force&next=/ to force the approval_prompt for certain users (with missing tokens), but its seem to have no effect over google oauth.
Thanks
Using this setting does the trick:
SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = {
'access_type': 'offline',
'approval_prompt': 'force'
}
Use case example at http://psa.matiasaguirre.net/docs/use_cases.html#re-prompt-google-oauth2-users-to-refresh-the-refresh-token
Related
I am creating a flutter android app which uses google sign in. Once logged in, I recieve accesstoken and idtoken. I want to use this token to authenticate my backend which uses django social auth and
Login and return the authoken, if the user has already signed up, or
Register the user , login and return the user id and authtoken.
Is this possible ? If so please suggest any documents online or please explain how should I approach this.
Over the years of doing this again and again, I found the solution below works well for me. It creates clear understanding of who is doing what.
Basically, you need:
Django Rest framework-backed token authentication for normal API requests. Mostly your app works on this. Link: https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
Google or Facebook or any other login to issue an auth token in 1. Thus effectively FB/ Google shortcuts the process of typing in username and password.
This is achieved via the flow below:
New user comes in and signs in via FB/ Google
You get Fb/Google token and send it to your backend
You verify the validity of the token. Re-obtain user name and email from G/FB from the backend. Use these details to create a user account in your backend. DO NOT USE email provided from front-end for account creation (assuming email is your primary unique user identifier)
NOTE: Don't forget to check if account already exists. If it does, this is a returning user/ login and not a new user. In this case, validate and return valid Django Rest Token
Once 3 is complete, issue a Django REST framework Token in response to the request made in 3.
After 4, you have a token in your app. Use this token for normal requests.
Happy coding! Happy to answer follow-up questions.
it is possible,first you have to create your api using django Rest Framework,the link below can help you to create your backend and set a token for every user:
https://dev.to/amartyadev/flutter-app-authentication-with-django-backend-1-21cp
then you have to add social authentication to your backend,you can write it yourself or using link below to use library :
https://github.com/RealmTeam/django-rest-framework-social-oauth2
after this approach you have to create your flutter app,the below link is a useful resource to connect your backend and your flutter app :
https://www.asapdevelopers.com/flutter-login-app-with-python-backend/
I am using Superset 0.36 and set up successfully OAUTH2 login using my SSO- Okta. However the redirect uri http://[site]:8088/oauth-authorized/okta that needs to be configured for Flask Application Builder to work redirects to a login page where the user needs to choose a provider and click sign-in. This is an unnecessary step since the user already logged into OKTA and should not need to login again.
Can someone help with any FAB configuration that would help set up an auto login using OAUTH2 so that we can bypass this redundant login page which my users find confusing and sometimes get stuck on. If there is no way to bypass it can someone tell me how I can customize the login page to instruct users how to use it?
I had the same issue (although not with Okta, and version 0.37). From the javascript in that login page I figured out the final URL. Look at the signin function that’s called when you click the button:
function signin() {
if (currentSelection != "") {
window.location.href = baseLoginUrl + currentSelection + next;
}
}
In your case I guess it would be something like:
http://[site]:8088/login/okta/?next=[dashboard]
Disclaimer: I’m absolutely not sure if this is the proper way to do it, but in my case it was just a POC so it didn’t matter much.
Also you should make sure you understand those 3 settings in superset_config.py regarding the Superset session cookie behavior in HTTP vs. HTTPS:
SESSION_COOKIE_HTTPONLY = False
SESSION_COOKIE_SAMESITE = "None"
SESSION_COOKIE_SECURE = True
And of course this makes sense only if you want to allow 1 authentication provider.
I'm wondering, why use Login when you have an Authentication Token?
I mean I'm using Postman to test my urls, serializers and views.
I can log in and I have to use a different urls to get my access token and my refresh token.
Login: POSThttp://localhost:8000/login/
{
"username":"Max",
"password":"Yolo1234"
}
-----
{
"id": 2,
"username": "Max",
"is_a": true,
"is_e": false
}
Token: POSThttp://localhost:8000/api/token/
{
"username":"Max",
"password":"Yolo1234"
}
-----
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTU4Nzc1OTQ5NCwianRpIjoiOWUzNjg1OTZhZWViNDRiNWE2Nzg3Y2E0ZDhkODQ5OWQiLCJ1c2VyX2lkIjoyfQ.W9a2fCxUF9Hrf51l-Ecx7nt2tmt2QvLhr4pp2DBUuvE",
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTg3NjgwMjk0LCJqdGkiOiIwNDI3MmJhMjljNmM0ODk3ODg4YTI5YTBkZjViZDljZCIsInVzZXJfaWQiOjJ9.0sid4rSbDUX3LHX7X74Cw1H9_lSlwD5ppfC3ctLGFSo"
}
And when I'm trying to POST an article, I need to authenticate with my access token.
But when I log out, I can still POST an article by using my access token without being logged in.
So I have some difficulty understanding the need to have the two in the project.
Thanks for your answers!
Tokens are usually the preferred way for API to authenticate since it is described in RFC such as RFC 7235.
However browsers are not able to deal with tokens - they are not very... convenient to humans.
Instead, sites have been using cookies to store session identifiers and websites can flag a session as being authenticated or not. The authentication is possible through login/logout pages where the website can ensure the username / password matches and then flag the session with that information. Hopefully, it'll not be stored client side for obvious security reasons. DRF uses SessionAuthentication for that.
It is quite handy when the user logs in on a website and can use that session on the API without requiring extra action from the user.
Note that you may use session authentication with other things than browsers but that's usually not what is done.
I would like to use django-rest-framework token to authenticate users. My workflow would be:
User requests a page
If auth token is present, respond with the requested data.
If auth token is not present, redirect to the login page (with the request page).
Inside the login page, user submit their credentials
If credentials were correctly authenticated, get or create a token for that user and redirect back to the requested page with the token.
Else, respond with error.
Lastly,
When the user logs out, delete the token for that user.
So my question is, is it okay to delete and create a new token for every login if the user has already logged out? Also I assume the token will be unique, am I correct? Your help and guidance is very much appreciated. Thank you.
A REST API should be stateless, that means that there should not be a "session" hence no login and no logout, and no redirections to a login page.
If the request doesn't have a token then the API should return (probably) a 401 Unauthorized HTTP status code and not a redirection. You're making an API so there won't be human interaction. Django rest framework offers a human-friendly interface that does have sessions, login/logout, and if that's all you need the go for it, you can do whatever you want. But It'd be hard for another program to use your API.
why not using tokens with expiration dates or using another well known authentication method ?? :P
Hope this helps :)
Let's say I have an AngularJS application that consumes the REST API of a Django application.
The Django application has got a built-in OAuth2 provider that can be called to retrieve an access token and use the protected endpoints of the API. This provider is using django-oauth-toolkit.
Let's assume there is a registered client with "password" grant type, so that the end users only need to provide their credentials in the front-end in order to get an access token from the back-end.
At some point we want to add some support for social networks login and we decide to use python-social-auth (PSA) to that end. Here is the workflow I want to achieve:
The user logs in on Facebook from the front-end (via the Facebook SDK) and we get an access token back from the OAuth2 provider of Facebook.
We send the Facebook token to an endpoint of our REST API. This endpoint uses the Facebook token and django-social-auth to authenticate the user in our Django application (basically matching a Facebook account to a standard account within the app).
If the authentication succeeds, the API endpoint requests an access token from the OAuth2 provider for this newly authenticated user.
The Django access token is sent back to the front-end and can be used to access the REST API in exactly the same way that a regular user (i.e. logged in with his credentials) would do.
Now my problem is: how do I achieve step 3? I first thought I would register a separate OAuth2 client with Client Credentials Grant but then the generated token is not user-specific so it does not make sense. Another option is to use the TokenAuthentication from DRF but that would add too much complexity to my project. I already have an OAuth server and I don't want to set up a second token provider to circumvent my problem, unless this is the only solution.
I think my understanding of PSA and django-oauth-toolkit is not deep enough to find the best way of reaching my goal, but there must be a way. Help!
I managed to get something working using urllib2. I can't speak towards whether or not this is good practice, but I can successfully generate an OAuth2 token within a view.
Normally when I'd generate an access token with cURL, it'd look like this:
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/
So we're tasked with making urllib2 accomplish this. After playing around for some bit, it is fairly straightforward.
import urllib, urlib2, base64, json
# Housekeeping
token_url = 'http://localhost:8000/auth/token/'
data = urllib.urlencode({'grant_type':'password', 'username':<username>, 'password':<password>})
authentication = base64.b64encode('%s:%s' % (<client_id>, <client_secret>))
# Down to Business
request = urllib2.Request(token_url, data)
request.add_header("Authorization", "Basic %s" % authentication)
access_credentials = urllib2.urlopen(request)
json_credentials = json.load(access_credentials)
I reiterate, I do not know if this is in bad practice and I have not looked into whether or not this causes any issues with Django. AFAIK this will do this trick (as it did for me).