40.(后端)根据ID获取用户信息

1.根据ID查询用户接口

为了方便用户快速查看信息,我们后端应该提供一个查询用户信息的接口
通过get请求参数,获取到id,再使用user视图去获取id对应的数据即可

2.到模型中定义获取内容的函数

# /flask_shop/models.py
# 此文件用于建立数据库表的模型

# 需要针对数据库的模型
from flask_shop import db
# 对数据加密         检查密码
from werkzeug.security import generate_password_hash,check_password_hash
from datetime import datetime

# 创建公用数据库模型
class BaseModel:
    # 记录创建的时间
    create_time = db.Column(db.DateTime,default=datetime.now)
    # 记录修改密码的时间
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate = datetime.now)

# 需要继承数据库中的模型
class User(db.Model,BaseModel):
    __tablename__ = 't_user'
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(32), unique=True, nullable=False)
    pwd = db.Column(db.String(128))
    nick_name = db.Column(db.String(32))
    phone = db.Column(db.String(11))
    email = db.Column(db.String(32))

    # 对数据库的加密操作

    # # 模拟用户操作
    # u = User() # 获取到对象
    # u.password # 访问获取密码
    # u.password = '123'# 用户输入密码

    # 定义两个装饰器,用于访问密码时使用
    @property
    def password(self):
        return self.pwd
    
    # 用户存储时使用,存的是加密过后的数据,若要访问,得通过property装饰器
    # 用户先输入密码,传入到t_pwd,通过函数的加密返回给self.pwd;用户需要访问时,找到property
    # self.pwd,是数据库中的密码(加密过后);t_pwd是用户输入的密码(真实密码)
    @password.setter
    def password(self,t_pwd):
        self.pwd = generate_password_hash(t_pwd)
    
    # 用户二次访问之后,需要把加密过后的密码转成真实密码,与用户输入的密码进行比对
    def check_password(self,t_pwd):
        return check_password_hash(self.pwd,t_pwd)

    def to_dict(self):
        return {
            'id':self.id,
            'name': self.name,
            'nick_name':self.nick_name,
            'phone':self.phone,
            'email':self.email
        }
# 建立菜单的数据库
class Menu(db.Model):
    __tablename__ = 't_menu'
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(32),unique = True, nullable = False)
    level = db.Column(db.Integer)
    path = db.Column(db.String(32))
    # pid = db.Column(db.Integer)
    pid = db.Column(db.Integer, db.ForeignKey('t_menu.id'))
    # 建立一个自连接的数据,用于做子表
    children = db.relationship('Menu')

    # 由于前端的接收需要给出json数据,不可以直接去获取,所以得单独返回
    def to_dict(self):
        return {
            'id':self.id,
            'name': self.name,
            'level':self.level,
            'path':self.path,
            'pid':self.pid,
            # 子表中的内容需要单独返回,可以做一个递归或者循环
            # 'children': self.get_child_list()
        }
    def get_child_list(self):
        obj_child = self.children
        data = []
        for o in obj_child:
            data.append(o.to_dict)
        return data

3.通过id获取用户信息

先获取到用户的id,使用filter_by获取到模型中的User类,此时,就可以调用刚刚定义模型的方法。

# flask_shop/user/view.py
# 此文件用于处理关于用户的业务逻辑,视图都写在这

# 导入用户的蓝图对象,这里的user不是文件,是在user.py定义好的蓝图对象
from flask import request
from flask_shop.user import user,user_api
from flask_shop import models,db
from flask_restful import Resource
import re
from flask_shop.utils.message import to_dict_msg
from flask_shop.utils.tokens import generate_auth_token,verify_auth_token,login_requed
@user.route("/")
def index():
    return "Hello user"

# 用flask_restful实现注册功能
# 使用flask_restful 必须继承Resource类
class User(Resource):
    # get请求访问
    def get(self):
        # 防止没有用户id产生报错
        try:
            # 通过参数获取用户的id
            id = int(request.args.get('id').strip())
            usr = models.User.query.filter_by(id = id).first()
            print(type(usr))
            if usr:
                return to_dict_msg(200, usr.to_dict(), "获取用户成功!")
            else:
                return to_dict_msg(200, [], '没有此用户')
        except Exception as e:
            print(e)
            return to_dict_msg(10000)
    # post请求访问    
    def post(self):
        name = request.form.get('name')
        pwd= request.form.get('pwd')
        real_pwd = request.form.get('real_pwd')
        nick_name = request.form.get('nick_name')
        phone = request.form.get('phone')
        email = request.form.get('email')
        # 验证数据的正确性
        if not all([name,pwd,real_pwd]):
            return to_dict_msg(10000)
        if len(name)<2:
            return to_dict_msg(10001)
        if len(pwd)<2:
            return to_dict_msg(10012)
        if pwd != real_pwd:
            return to_dict_msg(10013)
        # 正则表达式验证手机号和邮箱
        # ^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$
        if not re.match(r'^1[35789]\d{9}$',phone):
            return to_dict_msg(10014)
        if not re.match(r'^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$',email):
            return to_dict_msg(10015)
        # 由于可能在数据库中会抛出异常,还是得做一个尝试
        try:
            # 提交数据
            # 注意这里的密码要加密处理,不可以直接返回给保存到数据库中得变量pwd,返回给函数password
            usr = models.User(name=name, password = pwd, nick_name = nick_name, phone = phone,email = email)
            db.session.add(usr)
            db.session.commit()
            return to_dict_msg(200)
        except Exception as e:
        #     return to_dict_msg(2000)
            print('-------------------------')
            print(e)


# flask_restful注册路由地址
user_api.add_resource(User,'/user')


# 后端登录的实现
# 使用get请求不安全
@user.route('/login',methods=['POST'])
# 调用验证是否登录的装饰器
# @login_requed
def login():
    # 从前端输入框中获取,此时还没写前端使用postman测试
    name = request.form.get('name')
    pwd= request.form.get('pwd')
    # 判断两个是否为非空值
    if not all([name,pwd]):
        return {'status':10000,'msg':'数据不完整'}
    if len(name) > 1:
        # SQLALCHEMY查询语句:获取用户字段,得到实例对象
        usr = models.User.query.filter_by(name =name).first()
        if usr:
            # 调用usr视图中的验证蓝图
            if usr.check_password(pwd):
                # 登录成功生成token,实现免密登录
                token = generate_auth_token(usr.id,10000000000)
                # 用于验证token是否可以使用
                verify_auth_token(token)
                return to_dict_msg(200,data={'token':token})
    return {'status':10001,'msg':'用户名或密码错误'}#防止用户暴力测试

4.Postman测试

在这里插入图片描述

<think>我们正在处理一个关于后端如何获取当前页面显示的用户ID的问题。根据用户提供的引用内容,我们可以从两个方面入手: 1. 引用[1]中提到了前端如何获取当前用户信息并显示。具体来说,前端通过一个`getCurrUser`函数向后端发起请求,后端返回响应,前端解析响应并显示用户名。 2. 引用[2]中提到了Cookie和Session机制,这通常用于在无状态的HTTP协议中保持用户状态。 因此,后端获取当前页面显示的用户ID,通常有两种方式: 方式一:通过前端在请求中携带的用户标识(如Session ID或Token),后端从Session或数据库中查找对应的用户ID。 方式二:如果前端直接将用户ID作为参数(例如在URL参数或请求体中)传递给后端,则后端可以直接获取。 但是,根据问题描述,当前页面显示的用户ID是由前端通过后端返回的数据显示的,而后端在生成页面时可能并不知道当前显示的是哪个用户(除非在每次请求中都携带用户标识)。 所以,通常情况下,后端在需要获取当前用户ID时,是通过用户登录后建立的会话(Session)来识别的。具体步骤如下: 1. 用户登录:用户输入用户名和密码,前端发送登录请求到后端。 2. 后端验证:验证通过后,后端创建一个Session(存储在服务器端),并将Session ID通过Cookie返回给前端。 3. 后续请求:前端在每次请求时自动携带该Cookie(包含Session ID),后端通过Session ID找到对应的Session,从而获取用户ID。 因此,后端获取当前用户ID的方法通常是从Session中获取。 但是,如果问题中的“当前页面显示的用户ID”是指其他用户的ID(例如,在查看某个用户资料页面时),那么该用户ID可能是通过URL参数传递的,后端需要从请求参数中获取。 所以,我们需要明确两种情况: 情况一:获取当前登录用户自己的ID -> 通过Session获取。 情况二:获取当前页面显示的其他用户的ID -> 通过URL参数、请求体等获取根据用户的问题,他可能更关心的是如何获取当前登录用户自己的ID(因为引用[1]中显示的是当前登录用户)。因此,我们重点说明情况一。 具体实现(以Java Servlet为例): 1. 在用户登录成功后,将用户ID存入HttpSession中: HttpSession session = request.getSession(); session.setAttribute("userId", userId); // userId是登录用户的ID 2. 在后续请求中,后端可以通过Session获取用户ID: HttpSession session = request.getSession(false); // 如果不存在session则返回null if (session != null) { String userId = (String) session.getAttribute("userId"); // 使用userId进行后续操作 } 注意:如果使用Token机制(如JWT),则用户ID通常包含在Token中,后端需要解析Token来获取用户ID。 另外,引用[2]中提到的Cookie机制,实际上Session ID就是通过Cookie传递的,所以后端通过Session获取用户ID本质上是依赖Cookie的。 如果用户的问题是关于如何获取当前页面显示的其他用户的ID(比如在查看用户资料页面),那么通常是通过URL中的参数传递的。例如: https://example.com/user/profile?userId=123 后端可以通过获取请求参数来得到: String userId = request.getParameter("userId"); 综上所述,我们需要根据具体场景来决定如何获取用户ID。 现在,我们根据上述分析,给出结构清晰的回答。</think>### 后端获取当前页面用户ID的实现方法 在后端开发中获取当前页面显示的用户ID,主要通过以下两种方式实现: #### 1. **通过会话机制(Session)** - **核心原理**:用户登录后,服务器创建唯一会话标识(Session ID)并存储在服务器内存/数据库中,同时通过Cookie返回给浏览器 - **实现步骤**: 1. 用户登录时,后端验证凭证后创建Session: ```java // Java示例(Servlet) HttpSession session = request.getSession(); session.setAttribute("userId", "user123"); // 存储用户ID ``` 2. 后续请求中,浏览器自动携带Session Cookie: ```http GET /profile HTTP/1.1 Cookie: JSESSIONID=abcde12345 ``` 3. 后端通过Session获取用户ID: ```java String userId = (String) request.getSession().getAttribute("userId"); ``` #### 2. **通过请求参数传递** - **适用场景**:显示其他用户信息的页面(如用户资料页) - **实现方式**: - **URL路径参数**: ```http GET /users/{userId}/profile ``` ```python # Flask示例 @app.route('/users/<user_id>/profile') def user_profile(user_id): return f"Displaying profile of {user_id}" ``` - **查询参数**: ```http GET /profile?userId=user123 ``` ```nodejs // Express示例 app.get('/profile', (req, res) => { const userId = req.query.userId; }); ``` ### 关键注意事项 1. **安全验证**: - 对敏感操作(如修改用户数据)需验证当前登录用户与目标用户ID的归属关系 - 示例验证逻辑: ```python if current_session_user_id != requested_user_id: return "Unauthorized", 403 ``` 2. **前端配合**: - 根据引用[1]的`getCurrUser`实现,前端应在登录后通过API获取当前用户信息: ```javascript // 前端示例(基于引用[1]) async function getCurrUser() { const res = await fetch('/api/current-user'); const data = await res.json(); document.getElementById('userName').innerText = data.userId; } ``` 3. **无状态方案(JWT)**: ```mermaid sequenceDiagram 前端->>后端: 登录请求(含凭证) 后端->>前端: JWT(含用户ID) 前端->>后端: 后续请求(Authorization: Bearer <JWT>) 后端->>后端: 解析JWT获取用户ID ``` ### 典型应用场景 | 场景 | 获取方式 | 示例 | |---------------------|----------------------|--------------------------| | 用户个人中心 | Session/JWT | 显示"我的订单" | | 管理员查看用户资料 | URL路径参数 | `/admin/users/{userId}` | | 跨服务调用 | JWT令牌传递 | 微服务间身份传递 | > **安全提示**:永远不要信任客户端直接传递的用户ID,必须通过服务器会话或加密令牌验证身份[^1][^2]。对于敏感操作,应实施权限控制(如RBAC模型)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想成为数据分析师的开发工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值