用Flask创建登陆服务器,并且获取服务器数据的程序

1、任务

让用户登陆网站,登陆成功后能够获得网站的数据。

2、原理

当用户登陆成功后,服务器会返回一个token给用户或者第三方,任何挟带这个token的请求在token过期之前,都能够访问该服务器资源。

3、思路

创建一个程序用于处理用户登陆请求,当用户登陆成功之后,返回给用户一个token;再创建一个验证程序,挟带该token去访问服务器资源,如果能够返回希望的结果则认为该用户登陆成功了,否则,认为登陆失败了。登陆的方法我们使用python的Requests库。

4、服务器程序具体步骤

4.1、存储用户信息的变量user

用字典来代表一个用户,键值代表用户名,值代表密码。

# user info
user = {
    'liuchunming': ['12345']
}

4.2、创建处理用户登陆的程序

该程序在请求头中找到Authorization字段,并进行base64解密,解密之后的密码和用户存储的密码进行对比,如果一致则代表登陆成功,将会返回一个token。如果不一致则代表登陆失败。

@app.route('/login', methods=['POST','GET'])
def login():
    uid,password = base64.b64decode(request.headers['Authorization'].split(' ')[-1]).split(':')
    if user.get(uid)[0] == password:
        return gen_token(uid)
    else:
        return 'error'

4.3、创建验证用户登陆成功的后能够获取数据的程序

用户登陆成功后,挟带token向服务器再次发送请求来获取数据。在请求的参数中传递token变量,该程序获得请求头中的token,并利用verify_token进行验证,如果该token有效则返回data,如果token无效则返回error。

@app.route('/testlogin',methods=['POST','GET'])
def test():
    token = request.args.get('token')
    if verify_token(token) == 1:
        return 'data'
    else:
        return 'error'

4.4、定义生成token的程序

由于我们登陆成功后,会生成一个token,并返回给用户。因此,需要定义一个生成token 的方法。

这里使用base64加密算法对用户名和随机数和当前时间加7200秒的组合进行加密,生成一个token。将这个token append到用户的密码部分。这样用户的密码部分就有两部分组成,第一部分是用户密码第二部分是token。

def gen_token(uid):
    token = base64.b64encode(':'.join([str(uid),str(random.random()),str(time.time() + 7200)]))
    user[uid].append(token)
    return token

4.5、定义验证token是否有效的程序

先将请求传过来的token进行base64解密,在解密之后的token中用冒号切分得到用户名,再根据用户名得到登陆时生成的token,如果传进来的token与用户登陆时生成的token不一致,返回-1,如果一致并且token没有过期则返回1,如果过期了则返回0。

def verify_token(token):
    _token = base64.b64decode(token)
    if not user.get(_token.split(':')[0])[-1] == token:
        return -1
    if float(_token.split(':')[-1]) >= time.time():
        return 1
    else:
        return 0

5、客户端程序步骤

5.1、客户端请求登陆的程序

将用户名和密码编成一个元组传递给requests的auth参数中,requests会将其编码成请求头中的Authorization参数并传递出去。我们打印该请求生成的token

r = requests.get('http://127.0.0.1:5000/login',auth=('liuchunming','12345'))
print r.text
执行该程序可以生成一个token(每次执行该请求,token都不一样):

bGl1Y2h1bm1pbmc6MC4yNTQ0NDE5NDE2MDk6MTQzMDk4NzE3MS41Mw==

5.2、客户端获取数据的程序

如果用户登陆成功,则用户可以携带登录时生成的token,到服务器上去获得数据。

token = 'bGl1Y2h1bm1pbmc6MC4yNTQ0NDE5NDE2MDk6MTQzMDk4NzE3MS41Mw=='
r = requests.get('http://127.0.0.1:5000/testlogin',params={'token':token})
print r.text
在token过期之前(7200秒),客户端可以获得服务器端的数据data,如果过期了,或者携带的token不是最近一次登陆时生成的,则会返回error。

6、服务器端源代码

from flask import Flask
from flask import request
import base64
import time
import random

app = Flask(__name__)

# user info
user = {
    'liuchunming': ['12345']
}


# generate token
def gen_token(uid):
    token = base64.b64encode(':'.join([str(uid),str(random.random()),str(time.time() + 7200)]))
    user[uid].append(token)
    return token

#verify token
def verify_token(token):
    _token = base64.b64decode(token)
    if not user.get(_token.split(':')[0])[-1] == token:
        return -1
    if float(_token.split(':')[-1]) >= time.time():
        return 1
    else:
        return 0

#if login success,return a token to user
@app.route('/login', methods=['POST','GET'])
def login():
    uid,password = base64.b64decode(request.headers['Authorization'].split(' ')[-1]).split(':')
    if user.get(uid)[0] == password:
        return gen_token(uid)
    else:
        return 'error'

#create a test route for verify login success or not
@app.route('/testlogin',methods=['POST','GET'])
def test():
    token = request.args.get('token')
    if verify_token(token) == 1:
        return 'login_success'
    else:
        return 'login_error'


if __name__ == '__main__':
    app.run(debug=True)


已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页