Django项目实现微博授权登录
前言
前段时间我的老板让我写一个小功能,说现在的用户进入一个新的网站时,很多时候是不想去注册的,最好可以用一些他们本身就用的其他应用的账户来授权登录。本文就是从这个现象来说一说用户使用第三方账号登录我们的网站,主要说的是这里面的原理和过程,无所谓开发语言或者框架也无所谓是哪个第三方应用,只不过其中的样例代码用到的是django框架和微博。
OAuth2.0协议
想要让用户在第三方应用的账号登录我们的应用,都绕不开一个东西,就是OAuth2协议,具体概念和描述大家可以自行百度,我在下面也放了一个当时自己找到的文章链接。需要注意的是,在关于OAuth2的解释中提到的第三方应用,说的其实就是我们自己写的应用。比如,用户在登录我们自己写的应用(以下简称myweb)时,选择微博登录,此时的流程就是这样的:
- 用户访问myweb登录页,选择通过微博账号登录
- 用户登录微博账号,此时就是微博在验证用户的登录
- 微博验证通过之后,用户告诉微博,我要登录一个第三方的应用(myweb)。严谨一些的可以在这里设置授权,限制第三方应用能够获取的信息范围
- 微博来到第三方应用的后调地址,告诉第三方应用,这个用户是我们家孩子,现在要访问你们,你有什么想知道的直接来找我
- myweb说“好,这可是你说的,我是有证据的”。然后放行,用户进入到myweb正常登录进来的展示页面
现在写一个第三方授权登录的功能其实很简单,像微博、微信这些相对于我们myweb来看的第三方平台早就封装好OAuth2的接口。我们要做的就是在对应的平台上注册网站,然后调接口就行了,三方平台上都有详细的官方文档描述。下面附一份OAuth2.0的详细介绍:
https://blog.csdn.net/weixin_40972073/article/details/126204163
具体实现
创建django项目
这一步没什么说的,就是创建一个django项目,这里项目命名还是叫myweb,在创建一个应用myapp。这里至少需要两个页面,一个是登录页另一个是登录后的展示页。在myapp目录下创建模板目录templates,再在templates目录下创建应用名目录myapp,在myapp/templates/myapp/下创建文件login.html和home.html
登录页我直接继承django后台管理admin的登录页,然后添加一个微博登录的a标签:
{% extends "admin/login.html" %}
{% block content %}
<form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
<div class="form-row">
{{ form.username.errors }}
{{ form.username.label_tag }} {{ form.username }}
</div>
<div class="form-row">
{{ form.password.errors }}
{{ form.password.label_tag }} {{ form.password }}
<input type="hidden" name="next" value="{{ next }}">
</div>
{% url 'admin_password_reset' as password_reset_url %}
{% if password_reset_url %}
<div class="password-reset-link">
<a href="{{ password_reset_url }}">忘记账号或密码</a>
</div>
{% endif %}
<div class="submit-row">
<input type="submit" value="登录">
</div>
<div class="form-row">
<center>
<h2>第三方账号登录</h2>
<a href=#>微博登录</a>
</center>
</div>
</form>
{% endblock %}
home页面就简单点:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>网站首页</title>
</head>
<body>
<h1>欢迎进入首页</h1>
</body>
</html>
在myapp目录下创建forms.py文件,定义一个登录表单类:
# myapp/forms.py
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(label="用户名",max_length=100)
password = forms.CharField(label="密码",widget=forms.PasswordInput())
添加视图函数:
# myapp/views.py
from django.shortcuts importt render,redirect
from django.contrib.auth import authenticate,login as auth_login
from django.contrib.auth.decorators import login_required
from .forms import LoginForm
# 登录
def login(request):
if request.method == "POST":
form = LoginForm(request.POST)
# 本地用户登录验证
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(request=request,username=username,password=password)
if user is not None:
auth_login(request-request,user=user)
return redirect("/home/")
else:
form.add_error(None,"用户名或密码错误")
else:
form = LoginForm()
return render(request,"myapp/login.html",{"form":form})
# 三方平台授权登录的回调url
def process(request):
return redirect("/enter/index/")
# 主展示页
@login_required(login_url="/login/")
def home(request):
return render(request,"myapp/home.html")
配置路由:
# myweb/urls.py
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
# 子路由分发
path("",include("myapp.urls"))
]
myapp目录下创建子路由文件urls.py
# myapp/urls.py
from django.urls import path
from .views import *
urlpatterns = [
path("login/",login),
path("process/",process),
path("home/",home),
]
微博开放平台注册
-
进入微博开放平台,首次进入的先填写开发者信息
-
选择微连接 -> 网站接入 -> 立即接入
-
填写应用名称,应用分类选择网页应用,确认创建
-
创建完成之后就可以在 我的应用 中看到新创建的应用,点击应用就可以看到我们新创建的应用,应用状态显示在开发阶段,不用着急去补充后面的资料。(这也是我选择用微博举例的原因,其他的都必须要审核通过才可以往后面做)
-
下面有一个应用基本信息,记住App Key和App Secret的值,很关键
-
左侧导航栏下 -> 应用信息 -> 高级信息 -> 编辑OAuth2.0 授权设置 -> 添加授权回调页的url,例如:http://127.0.0.1:8000/process/ -> 确认保存
修改django项目微博登录的链接
在上面创建django项目的时候,login.html文件的微博登录a标签我是没有给href属性赋值的,要实现跳转到微博登录就需要调用微博开放平台给出的接口oauth2/authorize:
<!-- login.html -->
<!-- ... -->
<div class="form-row">
<center>
<h2>第三方账号登录</h2>
<a href="https://api.weibo.com/oauth2/authorize?client_id=1811751266&redirect_uri=http://127.0.0.1:8000/process">微博登录</a>
</center>
</div>
这里只是演示代码,所以我直接把这个接口需要的参数直接写死在a标签里的,具体参数和接口介绍可以查看微博开放平台的API。操作步骤:微博开放平台 -> 文档 -> 左侧导航栏微博API -> 微博API
链接:
https://open.weibo.com/wiki/%E5%BE%AE%E5%8D%9AAPI
每个接口点进去都有详细介绍,这里简单说一下。用户登录的时候我们需要调用oauth2/authorize接口,微博验证用户成功之后会返回一个code,然后跳转到我们设置好的回调地址,跳转的同时会将这个code也带过来。然后就是我们的回调地址的视图函数处理逻辑了,我们可以在这先调用oauth2/access_token拿到用户在微博授权的访问令牌,以这个令牌最为主要参数去从微博那里获取用户的信息,如调用account/profile/email获取用户的邮箱等等
然后就没有然后了,直接运行django项目就可以了。当然这里只是做一个代码演示,真实开发的话还需要将三方平台的账号与我们项目本地用户做关联。这些东西都有现成的三方库可以用,例如django-allauth、social-django等等