花了两天终于搞定了,记录一下,方便自己日后查看(大部分参考了网上的大神)
要实现github第三方登录,首先你必须要有github账号呀,so,登陆到 github官网 注册
在你的github账号中的profile里面找到Oauth application ,在Homepage URL和Authorization callback URL里面都填 http://localhost:8000,这里被坑了好久 :( ( PS: 真心蛋疼 )
一般申请第三方登录都需要经过几个步骤:
- 跳转到第三方认证界面
- 填写第三方登录的账号
- 经过回调redirect_uri 回调到自己网页
废话不多说,直接上代码吧
# 在settings中
# github第三方登录配置
# 请求gihhub第三方登录url
GITHUB_AUTHORIZE_URL = 'https://github.com/login/oauth/authorize'
GITHUB_CLIENTID = 'client_id'
GITHUB_CLIENTSECRET = 'client_secret'
# 这里是github认证处理的url,就是自己处理登陆逻辑(被坑好好久)
GITHUB_CALLBACK = 'http://localhost:8000/oauth/github/'
# 新建一个oauth app
# python manage.py startapp oauth
# 在oauth/urls.py中
urlpatterns = [
url(r'github/$', views.github_auth,name='github_oauth'),
url(r'github_login/$', views.githhub_login, name='github_login'),
]
# 在oauth/veiws.py中
GITHUB_CLIENTID = settings.GITHUB_CLIENTID
GITHUB_CLIENTSECRET = settings.GITHUB_CLIENTSECRET
GITHUB_CALLBACK = settings.GITHUB_CALLBACK
GITHUB_AUTHORIZE_URL = settings.GITHUB_AUTHORIZE_URL
# 这里不是很明白
def _get_refer_url(request):
refer_url = request.META.get('HTTP_REFER',
'/index(自己的首页)')
host = request.META['HTTP_HOST']
if refer_url.startswith('http') and host not in refer_url:
refer_url = '/index'
return refer_url
# 第一步: 请求github第三方登录
def githhub_login(request):
data = {
'client_id': GITHUB_CLIENTID,
'client_secret': GITHUB_CLIENTSECRET,
'redirect_uri': GITHUB_CALLBACK,
'state': _get_refer_url(request),
}
github_auth_url = '%s?%s' %
(GITHUB_AUTHORIZE_URL,urllib.parse.urlencode(data))
print('git_hub_auth_url',github_auth_url)
return HttpResponseRedirect(github_auth_url)
# github认证处理
def github_auth(request):
template_html = 'account/login.html'
# 如果申请登陆页面成功后,就会返回code和state(被坑了好久)
if 'code' not in request.GET:
return render(request,template_html)
code = request.GET.get('code')
# 第二步
# 将得到的code,通过下面的url请求得到access_token
url = 'https://github.com/login/oauth/access_token'
data = {
'grant_type': 'authorization_code',
'client_id': GITHUB_CLIENTID,
'client_secret': GITHUB_CLIENTSECRET,
'code': code,
'redirect_uri': GITHUB_CALLBACK,
}
data = urllib.parse.urlencode(data)
# 请求参数需要bytes类型
binary_data = data.encode('utf-8')
print('data:', data)
# 设置请求返回的数据类型
headers={'Accept': 'application/json'}
req = urllib.request.Request(url, binary_data,headers)
print('req:', req)
response = urllib.request.urlopen(req)
# json是str类型的,将bytes转成str
result = result.decode('ascii')
result = json.loads(result)
access_token = result['access_token']
# print('access_token:', access_token)
url = 'https://api.github.com/user?access_token=%s'
% (access_token)
response = urllib.request.urlopen(url)
html = response.read()
html = html.decode('ascii')
data = json.loads(html)
username = data['name']
# print('username:', username)
password = '111111'
# 如果不存在username,则创建
try:
user1 = User.objects.get(username=username)
except:
user2 = User.objects.create_user(username=username,
password=password)
user2.save()
profile = Profile.objects.create(user=user2)
profile.save()
# 登陆认证
user = authenticate(username=username,
password=password)
login(request, user)
return HttpResponseRedirect(reverse('index'))
写在最后,谢谢下面博主提供的参考资料,:
http://qinxuye.me/article/third-party-authentication-in-django/