我希望有许多不同的客户能够访问我的django网站(更具体地说,它的API),但我不知道如何使用django-allauth,dj-rest-auth和simplejwt。
我当前的客户端应用程序使用的是内置的django模板引擎,它是用django-allauth建立的,用于社会认证(Google等)。它使用的是文档化的安装建议。
现在,我想创建不同类型的客户机,这些客户端不使用django模板引擎(例如角、Vue、颤振移动等),但我不知道如何使用dj-rest-auth来支持任意数量的客户端类型。
以Google登录为例,当我创建一个新客户端时,我必须注册一个特定于该客户端的新redirect_uri。
为了测试这一切,我创建了一个简单的烧瓶应用程序,只有一个链接,这样我就可以在将其发送到Django应用程序之前检索"code/access_token“。该链接是使用以下方法创建的.
var codeRequestUrl =
`https://accounts.google.com/o/oauth2/v2/auth?\
scope=email&\
access_type=offline&\
include_granted_scopes=true&\
response_type=code&\
state=state_parameter_passthrough_value&\
redirect_uri=http%3A//127.0.0.1:5000/callback&\
client_id=${clientId}`;...and在烧瓶中的‘/回调’端点检索代码.
@app.route("/callback", methods=['GET'])
def redirect():
code = request.args.get('code', '')
req = requests.post('http://127.0.0.1:8000/api/dj-rest-auth/google/', data={'code':code})
return "done..."在...from中,我将x-www-form-urlencoded的POST请求发送回dj-rest-auth端点,该端点是根据其文档设置的.
class GoogleLogin(SocialLoginView):
callback_url = 'http://127.0.0.1:5000/callback'
adapter_class = GoogleOAuth2Adapter
client_class = OAuth2Client
...
urlpatterns += [
...
path('dj-rest-auth/google/', GoogleLogin.as_view(), name='google_login'),
....
]Django然后成功地返回一个access_token、refresh_token和一些有关登录用户的信息。
但这可不是什么好东西。如果我也要创建一个角客户机,我需要注册一个不同的回调(因为这个角客户机将运行在不同的端口和/或地址上,我还需要在urls.py中设置另一条路径,并将它与能够处理不同callback_url (redirect_uri)的新的SocialLoginView子类关联起来。
考虑到所有这些,我不知道如何使用一个颤振的移动应用程序,据我所知,它没有callback_url的概念,所以我不知道向.../dj-rest-auth/google/发出一个POST请求是如何工作的,因为我马上就会收到redirect_uri_mismatch错误。
我把它倒过来了,在谷歌注册的客户端是角形,Vue,Flash等应用程序吗?这意味着每个客户端都必须处理自己的client_id和client_secret,后者似乎绕过了django-allauth和dj-rest的功能。
我觉得我误解了这一点,所以我非常感谢你给我一些建议。
发布于 2022-11-02 07:03:19
我有足够的信心回答我自己的问题。简而言之,是的,多个客户(包括第三方)是一个相当直接的过程。不幸的是,存在的许多博客文章和教程都是从“第二方”客户端的角度出发的,这确实会让事情变得混乱。结果是大量与redirect_uri相关的错误消息。
值得赞扬的是,谷歌的实例瓶应用程序文档正是我所需要的,但是有几个观察非常重要,也是什么给我造成了如此多的混乱。
首先,也是最重要的一点,在Django中根本不需要回调(redirect_uri)。在Django中,需要这样的东西。
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
class GoogleLogin(SocialLoginView):
adapter_class = GoogleOAuth2Adapter
client_class = OAuth2Client
urlpatterns += [
...
path('auth/google/', GoogleLogin.as_view(), name='google_login'),
...
]因此,不需要回调属性。这样做的原因是,Flask (或第三方应用程序)处理Google端的所有身份验证。
第二个观察是,对于“代码”请求步骤和"access_token“步骤,Flask应用程序中的access_token似乎都必须是相同的。
您可以在链接的示例中看到它,其中oauth2callback函数(它处理redirect_uri),但是我已经修改了dj auth。
@app.route('/')
def index():
if 'credentials' not in flask.session:
return flask.redirect(flask.url_for('oauth2callback'))
credentials = json.loads(flask.session['credentials'])
if credentials['expires_in'] <= 0:
return flask.redirect(flask.url_for('oauth2callback'))
else:
data = {'access_token': credentials['access_token']}
headers = headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post(f'{URL_ROOT}/api/auth/google/', data=data, headers=headers)
response_json = json.loads(r.text)
access_token = response_json['access_token'] # JWT Access Token
refresh_token = response_json['refresh_token']
# Make a query to your Django website
headers = headers = {'Authorization': f'Bearer {access_token}'}
r = requests.post(f'{URL_ROOT}/api/object/{OBJECT_ID}/action/', data=data, headers=headers)
# do stuff with r
@app.route('/oauth2callback')
def oauth2callback():
if 'code' not in flask.request.args:
auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
'&client_id={}&redirect_uri={}&scope={}').format(CLIENT_ID, REDIRECT_URI, SCOPE)
return flask.redirect(auth_uri)
else:
auth_code = flask.request.args.get('code')
data = {'code': auth_code,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'grant_type': 'authorization_code'}
r = requests.post('https://oauth2.googleapis.com/token', data=data)
flask.session['credentials'] = r.text # This has the access_token
return flask.redirect(flask.url_for('index'))总之,它有点像这样:
/login的"Login“html锚点。/oauth2callback开始身份验证。/auth端点以及应用程序的客户端id检索“代码”。redirect_uri确保代码流返回到自己,但这次,使用“代码”现在知道,使用应用程序的客户端id和客户端机密向谷歌的/token端点发送一个帖子请求。同样,redirect_uri是相同的(/oauth2callback)。我希望这能帮到你。
请注意,您的烧瓶应用程序将需要注册为一个新的Web与谷歌的OAuth2控制台(因此,它有自己的客户端id和客户端机密)。换句话说,不要重复使用现有Django allauth实现已经创建的内容(这是我的场景)。每个第三方应用程序制造商都将处理自己的OAuth2凭证。
https://stackoverflow.com/questions/74078147
复制相似问题