用access将两个表合成一个表_从头搭建一个flask鉴权系统之登陆

 从今天开始,准备从头开始搭建一个基于flask的鉴权系统,一点一滴,积累于生活

从登陆开始

01.知识树

本文涉及到如下知识点

1. flask-login的简单使用

2. 本地鉴权实践

3. GitHub鉴权登陆实践,flask-github使用

4. 可扩展的表结构设计思路

02.表结构设计

我们首先设计一个User用户表,里面的字段可以包括username,password,email等用户信息,大致如下

usernamepasswordemail
user1p1user1@gmail.com
user2p2user2@gmail.com
user3p3user3@gmail.com

因为我们还会涉及到第三方登陆,那么为了后面便于扩展,再设计一张表,就命名为ThirdAuth,里面可以包括user_id,与user表关联,oauth_name,oauth_access_token等字段

user_idoauth_nameoauth_access_token
user-id1auth1token1
user-id2auth2token2
user-id3auth3token3

这样,oauth_name字段可以用来存储第三方来源,例如github,以此来区别不同的第三方登陆用户。

到此,一个简单的表结构就设计好了。

03.OAuth鉴权

简单来说,为一个网站添加第三方登录指的是提供通过其他第三方平台账号登入当前网站的功能。比如,使用QQ、微信、新浪微博账号登录。对于某些网站,甚至可以仅提供社交账号登录的选项,这样网站本身就不需要管理用户账户等相关信息。对用户来说,使用第三方登录可以省去注册的步骤,更加方便和快捷。这里,我就是使用GitHub的OAuth认证来进行鉴权登陆。

这里首先需要在自己的GitHub上创建一个OAuth程序,非常简单,访问这个地址:https://github.com/settings/applications/new,按照要求填写即可。

744718b9cd22f8aed1aee36cf08800a8.png

其中的callback需要填写一个回调函数,具体后面再说。

创建好这个OAuth程序后,我们就会获得Client ID(客户端ID)和Client Secret(客户端密钥),在后面调用Github的API时使用。

04. 本地鉴权

1. 创建表结构

根据刚才的表结构设计,对于本地鉴权,可以在models.py文件中创建一个WebUser类,定义对应的数据库字段。

对于password,不建议直接在数据库中存储明文,所以这里使用了werkzeug库来做hash转换。

同时WebUser类还继承自flask-login的UserMixin类,该类实现了关键的用于检测用户状态的方法:

    is_authenticated,如果用户已经登陆返回True,否则返回False

    is_active,如果用户允许登陆,返回True,否则返回Flase

    is_anonymous,对普通用户必须返回False

    get_id,必须返回用户的唯一标识

后面主要使用到了is_authenticated方法。

而init_user是用来初始化第一个用户的,password等几个方法分别是用来检测密码是否正确的。

class WebUser(UserMixin, db.Model):

2. 定义登陆表单

登陆表单比较简单,两个输入框,分别为用户名和密码,一个check box,用来选择是否保持登陆,外加一个提交按钮

class LoginForm(FlaskForm):

3. 定义登陆登出函数

当表单正确提交时,如果用户名和密码匹配,则提示登陆成功,并跳转页面,否则提示登陆失败。

因为是使用flask-login扩展,所以登陆直接调用login_user()即可。

@auth.route('/login', methods=['GET', 'POST'])

对于登出,同样简单,注意需要用login_required装饰器保证只有已经登陆的用户才能调用该函数。

@auth.route('/logout')

4. web模板

创建一个base.html基础模板(继承自flask-bootstrap模板),后面其他页面都继承自该模板,这样可以保证所有的页面风格统一,也可以减少代码量。

{% extends "bootstrap/base.html" %} 

{% block title %}Flasky{% endblock %} 

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle"  data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigationspan>
                <span class="icon-bar">span>
                <span class="icon-bar">span>
                <span class="icon-bar">span>
            button>
            <a class="navbar-brand" href="/">WebAutha>
        div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Homea>li>
            ul>
            <ul class="nav navbar-nav navbar-right">
                {% if current_user.is_authenticated %}
                <li><a href="{{ url_for('auth.logout') }}">Sign Outa>li>
                {% else %}
                <li><a href="{{ url_for('auth.login') }}">Sign Ina>li>
                {% endif %}
            ul>
        div>
    div>
div>
{% endblock %}

{% block content %}
<div class="container">
    {% block page_content %}{% endblock %}
div>
{% endblock %}

5. 登陆页面

登陆页面继承自base.html模板,并使用wtf快速渲染表单

{% extends "base.html" %}
{% import  "bootstrap/wtf.html" as wtf %}
{% block title %}Login{% endblock %}
{% block page_content %}
<div class="page-header">
    <h1>Loginh1>
div>

<div class="col-md-4">
    {{ wtf.quick_form(form) }}
div>
{% endblock %}

最后的登陆页面为

9a9fe9d6f603fc049d59e704a0f3da9b.png

6. 初始化数据库

使用flask-script扩展,定义runserver和shell两个命令行命令,shell用于数据库等调测操作,runserver用于启动服务。

from app 

在命令行输入python manage.py shell,进入调测shell,然后输入db.create_all()和WebUser.init_user(),分别创建表并插入原始用户。

7. 登陆测试

在输入框分别键入admin@163.com和123456,并点击登陆,发现可以正常登陆,效果如下

bc03c809ad92b5c6d19f8d7e75ace020.png

其中index页面代码为

"base.html" %}

{% endblock %}

05. GitHub鉴权

1. 创建表结构

类似的,定义需要的字段即可

class ThirdOAuth(db.Model):

2. 发送授权请求

这一步,flask-github已经为我们封装好了,直接调用即可

@auth.route('/githublogin', methods=['GET', 'POST'])

这里需要说明,该调用需要用到我们前面获得的客户端ID和密钥,我这里把相关信息写到了一个配置文件中,并在初始化flask app时加载

配置文件

class Config:

初始化app

def create_app(config_name):

3. 获取access令牌

当用户同意授权或拒绝授权后,GitHub会将用户重定向到我们设置的callback URL,我们需要创建一个视图函数来处理回调请求。如果用户同意授权,GitHub会在重定向的请求中加入code参数,一个临时生成的值,用于程序再次发起请求交换access token。程序这时需要向请求访问令牌URL(即https://github.com/login/oauth/access_token)发起一个POST请求,附带客户端ID、客户端密钥、code。请求成功后的的响应会包含访问令牌(Access Token)。

很幸运,上面的一系列工作flask-github会在背后替我们完成。我们只需要创建一个视图函数,定义正确的URL规则(这里的URL规则需要和GitHub上填写的Callback URL匹配),并为其附加一个github.authorized_handler装饰器。另外,这个函数要接受一个access_token参数,GitHub-Flask会在授权请求结束后通过这个参数传入访问令牌。

同时判断,该用户是否存在于数据库中,并更新相关字段。

@auth.route('/callback/github')

更多的GitHub开发文档资料可以查看:

https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/

更多flask-github资料可以查看:

https://github-flask.readthedocs.io/en/latest/

4. 更新登陆页面

更新登陆页面,增加一个以GitHub登陆的按钮

<div class="col-md-12">

现在的登陆页面为

b38d473f18d19db17b00277cc41afaf5.png

更新index路由函数,增加以GitHub登陆时的头像

@main.route('/', methods=['GET', 'POST'])

又因为在callback函数中增加了session.userid字段,所以在logout时,把该字段手动删除

@auth.route('/logout')

5. 测试GitHub登陆

登陆成功后,如下

4add60c1e3dff0d5a8e3635031f069de.png

至此,登陆功能完成

完整代码:

https://github.com/zhouwei713/flask-webauth


往期文章:

       使用sklearn+jieba完成一个文档分类器

      从头完成一个restful API服务

      从头搭建一个HTTPS网站

       运用百度API来测评女神的质量 

圣诞来临,爬取女神美图放松下

用Python探索红楼梦里的关系

Kubernetes系列入门文章

爬取女神王祖贤的海报评论,看看粉丝们是怎么说

果喜欢我的文章,那就关注我吧!

d8357eddfadbc85ed2b7c7978abbab4f.png

万分感谢!

欢迎留言讨论

f43a6418950c306a2f68703134867f11.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值