60 - restful接口案例(新闻)-08-用户认证权限

用户认证权限:

        在OAuth协议中,token是在输入了用户名和密码之后获取的,
        利用这个token你可以拥有查看或者操作相应的资源的权限。
        你有这些权限,是因为服务器知道你是谁 (authentication) 以后赋予你的,
        所以token这个东西,其实就是你的一个“代表”,或者说完全能代表你的“通行证”

 

1. apps \ apis \ user_api.py 登陆成功后返回给前端token

# 账号密码登录
class UserApi(Resource):
    def post(self):
        args = password_login_parser.parse_args()
        mobile = args.get("mobile")
        password = args.get("password")
        # 判断用户
        user = User.query.filter(User.phone == mobile).first()
        if user:
            if check_password_hash(user.password, password):
                # 说明这个用户是登陆成功的

                # 设置token
                token = str(uuid.uuid4()).replace("-", "") + str(random.randint(100, 999))
                print(token)
                # 存储用户的登录信息
                session[token] = mobile
                
                return {"status": 200, "msg": "用户登录成功", "token": token}


        return {"status": 400, "msg": "用户名或密码有误"}

2.  apps \ apis \ user_api.py 定义权限认证装饰器

from flask_restful import abort

# 验证前端传来的请求头中是否包含token
def check_user():

    # 前端请求时需要添加请求头Authorization
    auth = request.headers.get('Authorization') 
    if not auth:
        abort(401, msg="请先登录")
    mobile = session.get(auth)
    if not mobile:
        abort(401, msg="无效令牌")
    user = User.query.filter(User.phone == mobile).first()
    if not user:
        abort(401, msg="此用户已被管理员删除")
    g.user = user



# 登录验证装饰器
def login_required(func):
    def wrapper(*args, **kwargs):
        check_user()  # 先执行查看有没有token
        return func(*args, **kwargs)  # 后执行api
 
    return wrapper

3. apps \ apis \ news_api.py  api使用认证权限

        (1). 定义返回格式 和 参数校验
# 回复-返回格式
reply_fields = {
    'user': AuthorName(attribute="user"),  # 调用自定义输出,对象类.username
    'content': fields.String,
    "datetime": fields.DateTime(attribute="date_time"),
    "lovenum": fields.Integer(attribute="love_num"),
}
 
# 评论-返回格式
comment_fields = {
    'user': AuthorName(attribute="user"),
    'content': fields.String,
    "datetime": fields.DateTime(attribute="date_time"),
    "lovenum": fields.Integer(attribute="love_num"),
    "reply": fields.List(fields.Nested(reply_fields))  # 回复信息
}
 
# 详情-返回格式
news_detail_fields = {
    "id": fields.Integer,
    "title": fields.String,
    "content": fields.String,
    "datetime": fields.DateTime(attribute="date_time"),
    "author": AuthorName(attribute="author"),
    # fields.Nested:套件; comment_fields:评论的格式
    "comments": fields.List(fields.Nested(comment_fields))  # 评论信息
}
 
# 定义新闻添加 参数校验
add_news_parser = reqparse.RequestParser()
add_news_parser.add_argument("title", type=str, required=True, help="必须填写新闻标题",location='form')
add_news_parser.add_argument("content", type=str, required=True, help="必须填写新闻主题内容",location='form')
add_news_parser.add_argument("typeid", type=int, required=True, help="必须填写新闻类型id",location='form')
 
        (2). 定义api
# 新闻的添加
class NewsApi(Resource):
    @login_required  # 登录权限认证装饰器
    def post(self):
        args = add_news_parser.parse_args()
        title = args.get("title")
        content = args.get("content")
        typeid = args.get("typeid")
        # 数据库添加
        news = News()
        news.title = title
        news.content = content
        news.desc = content[10] + "..."
        news.news_type_id = typeid
        news.user_id = g.user.id
        db.session.add(news)
        db.session.commit()
        data={
            "status":200,
            "msg":"新闻发布成功",
            "news":marshal(news,news_detail_fields)
        }
        return data
        (3). 绑定路由
api.add_resource(NewsApi, '/news')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值