Django
配置Authok
获取应用密钥
你需要如下信息
- Domain
- Client ID
- Client Secret
配置回调URL
配置 Logout URL
集成 Authok
在requirements.txt
中添加依赖:
django~=2.1
social-auth-app-django~=3.1
python-jose~=3.0
python-dotenv~=0.9
执行以下命令安装依赖:
pip install -r requirements.txt
创建 Django工程
django-admin startproject webappexample
cd webappexample
python manage.py startapp authok_login
Django设置
webappexample\settings.py
INSTALLED_APPS = [
'social_django',
'<your application name>' # such as 'webappexample'
]
webappexample\settings.py
SOCIAL_AUTH_TRAILING_SLASH = False # Remove trailing slash from routes
SOCIAL_AUTH_AUTHOK_DOMAIN = 'YOUR_DOMAIN'
SOCIAL_AUTH_AUTHOK_KEY = 'YOUR_CLIENT_ID'
SOCIAL_AUTH_AUTHOK_SECRET = 'YOUR_CLIENT_SECRET'
webappexample\settings.py
SOCIAL_AUTH_AUTHOK_SCOPE = [
'openid',
'profile',
'email'
]
初始化数据库
python manage.py migrate
创建 Authok认证 后端服务
authok_login/authok_backend.py
from urllib import request
from jose import jwt
from social_core.backends.oauth import BaseOAuth2
class Authok(BaseOAuth2):
"""Authok OAuth authentication backend"""
name = 'authok'
SCOPE_SEPARATOR = ' '
ACCESS_TOKEN_METHOD = 'POST'
REDIRECT_STATE = False
EXTRA_DATA = [
('picture', 'picture'),
('email', 'email')
]
def authorization_url(self):
return 'https://' + self.setting('DOMAIN') + '/authorize'
def access_token_url(self):
return 'https://' + self.setting('DOMAIN') + '/oauth/token'
def get_user_id(self, details, response):
"""Return current user id."""
return details['user_id']
def get_user_details(self, response):
# Obtain JWT and the keys to validate the signature
id_token = response.get('id_token')
jwks = request.urlopen('https://' + self.setting('DOMAIN') + '/.well-known/jwks.json')
issuer = 'https://' + self.setting('DOMAIN') + '/'
audience = self.setting('KEY') # CLIENT_ID
payload = jwt.decode(id_token, jwks.read(), algorithms=['RS256'], audience=audience, issuer=issuer)
return {'username': payload['nickname'],
'first_name': payload['name'],
'picture': payload['picture'],
'user_id': payload['sub'],
'email': payload['email']}
在 settings.py 中注册.
webappexample\settings.py
AUTHENTICATION_BACKENDS = {
'YOUR_DJANGO_APP_NAME.authok_backend.Authok',
'django.contrib.auth.backends.ModelBackend'
}
webappexample\settings.py
LOGIN_URL = '/login/authok'
LOGIN_REDIRECT_URL = '/dashboard'
触发认证
authok_login/views.py
from django.shortcuts import render, redirect
def index(request):
user = request.user
if user.is_authenticated:
return redirect(dashboard)
else:
return render(request, 'index.html')
在 index.html
模版中添加 /login/authok
链接.
authok_login/templates/index.html
<div class="login-box authok-box before">
<img src="https://i.cloudup.com/StzWWrY34s.png" />
<h3>Authok例子</h3>
<p>零信任身份基础设施,专为开发者打造</p>
<a class="btn btn-primary btn-lg btn-login btn-block" href="/login/authok">登录</a>
</div>
显示用户信息
authok_login/views.py
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
import json
@login_required
def dashboard(request):
user = request.user
authok_user = user.social_auth.get(provider='authok')
userdata = {
'user_id': authok_user.uid,
'name': user.first_name,
'picture': authok_user.extra_data['picture'],
'email': authok_user.extra_data['email'],
}
return render(request, 'dashboard.html', {
'authokUser': authok_user,
'userdata': json.dumps(userdata, indent=4)
})
把以下代码加入dashboard.html
以展示用户信息.
authok_login/templates/dashboard.html
<div class="logged-in-box authok-box logged-in">
<h1 id="logo"><img src="//cdn.authok.cn/assets/authok-badge.png" /></h1>
<img class="avatar" src="{{ authokUser.extra_data.picture }}"/>
<h2>Welcome {{ user.username }}</h2>
<pre>{{ userdata }}</pre>
</div>
注销
在dashboard.html
中添加/logout
链接.
authok_login/templates/dashboard.html
<div class="logged-in-box authok-box logged-in">
<h1 id="logo"><img src="//cdn.authok.cn/assets/authok-badge.png" /></h1>
<img class="avatar" src="{{ authokUser.extra_data.picture }}"/>
<h2>Welcome {{ user.username }}</h2>
<pre>{{ userdata }}</pre>
<a class="btn btn-primary btn-lg btn-logout btn-block" href="/logout">Logout</a>
</div>
在 views.py
中添加logout
方法.
authok_login/views.py
# ...
from django.contrib.auth import logout as log_out
from django.conf import settings
from django.http import HttpResponseRedirect
from urllib.parse import urlencode
# ...
def logout(request):
log_out(request)
return_to = urlencode({'return_to': request.build_absolute_uri('/')})
logout_url = 'https://%s/v1/logout?client_id=%s&%s' % \
(settings.SOCIAL_AUTH_AUTHOK_DOMAIN, settings.SOCIAL_AUTH_AUTHOK_KEY, return_to)
return HttpResponseRedirect(logout_url)
添加URL映射
authok_login\urls.py
urlpatterns = [
path('', views.index),
path('dashboard', views.dashboard),
path('logout', views.logout),
path('', include('django.contrib.auth.urls')),
path('', include('social_django.urls')),
]
运行例子
python manage.py migrate
python manage.py runserver 3000
可通过 http://localhost:3000 访问应用.