精华内容
下载资源
问答
  • thinkphp6 auth

    2021-05-07 06:24:59
    Thinkphp6 认证安装composer require ric/thinkphp6-auth导入数据表本工具优化为多端权限认证,同时每端又支持通过传website_id实现同个应用saas权限制,并可通过配置auth_rule_unified参数来指定同个应用内是使用同...

    Thinkphp6 认证

    安装

    composer require ric/thinkphp6-auth

    导入数据表

    本工具优化为多端权限认证,同时每端又支持通过传website_id实现同个应用saas权限制,并可通过配置auth_rule_unified参数来指定同个应用内是使用同个权限规则还是通过website_id来区分多个权限规则

    toadmin_ 为admin后台端,默认无表前坠,有表前坠的请自行添加

    `------------------------------

    -- toadmin_auth_rule,规则表,

    ------------------------------

    DROP TABLE IF EXISTS `toadmin_auth_rule`;

    CREATE TABLE `toadmin_auth_rule` (

    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',

    `website_id` int(10) NOT NULL DEFAULT '0' COMMENT '站点id,用于多站点,默认0',

    `name` char(80) CHARACTER SET utf8 NOT NULL DEFAULT '' COMMENT '规则唯一标识',

    `title` char(20) CHARACTER SET utf8 NOT NULL DEFAULT '' COMMENT '规则中文名称',

    `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '在think_auth_rule 表中定义一条规则时,如果type为1, condition字段就可以定义规则表达式。 如定义{score}>5 and {score}<100 表示用户的分数在5-100之间时这条规则才会通过。',

    `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:为1正常,为0禁用',

    `condition` char(100) CHARACTER SET utf8 NOT NULL DEFAULT '' COMMENT '规则表达式,为空表示存在就验证,不为空表示按照条件验证',

    `pid` int(8) NOT NULL COMMENT '父级ID',

    `front` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT '前端标示,前端可以根据这个来判断是否显示按钮',

    `menu` tinyint(1) NOT NULL DEFAULT '0' COMMENT '菜单类型,0系统,1导航菜单,2功能按钮',

    `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '最后修改时间',

    `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '添加时间',

    PRIMARY KEY (`id`) USING BTREE,

    UNIQUE KEY `name` (`website_id`,`name`) USING BTREE

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

    ------------------------------

    -- toadmin_auth_group 用户组表,

    ------------------------------

    DROP TABLE IF EXISTS `toadmin_auth_group`;

    CREATE TABLE `toadmin_auth_group` (

    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',

    `website_id` int(10) NOT NULL DEFAULT '0' COMMENT '站点id,用于多站点,默认0',

    `title` char(100) NOT NULL DEFAULT '' COMMENT '用户组中文名称',

    `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:为1正常,为0禁用',

    `rules` varchar(600) NOT NULL DEFAULT '' COMMENT '用户组拥有的规则id, 多个规则","隔开',

    `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '最后修改时间',

    `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '添加时间',

    PRIMARY KEY (`id`) USING BTREE

    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

    ------------------------------

    -- toadmin_auth_group_access 用户组明细表,

    ------------------------------

    DROP TABLE IF EXISTS `toadmin_auth_group_access`;

    CREATE TABLE `toadmin_auth_group_access` (

    `uid` mediumint(8) unsigned NOT NULL COMMENT '用户id',

    `group_id` mediumint(8) unsigned NOT NULL COMMENT '用户组id',

    `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '最后修改时间',

    `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '添加时间',

    UNIQUE KEY `uid_group_id` (`uid`,`group_id`) USING BTREE,

    KEY `uid` (`uid`) USING BTREE,

    KEY `group_id` (`group_id`) USING BTREE

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

    ------------------------------

    -- toadmin_auth_user 用户账号表,

    ------------------------------

    DROP TABLE IF EXISTS `toadmin_auth_user`;

    CREATE TABLE `toadmin_auth_user` (

    `id` int(11) NOT NULL AUTO_INCREMENT,

    `website_id` int(10) NOT NULL DEFAULT '0' COMMENT '站点id,用于多站点,默认0',

    `name` varchar(20) NOT NULL COMMENT '姓名',

    `account` varchar(20) NOT NULL COMMENT '用户名',

    `password` varchar(32) NOT NULL COMMENT '用户密码',

    `email` varchar(255) NOT NULL COMMENT '邮箱',

    `tel` varchar(11) NOT NULL COMMENT '电话',

    `department` varchar(255) NOT NULL COMMENT '部门',

    `position` varchar(255) NOT NULL COMMENT '职位',

    `status` int(1) NOT NULL DEFAULT '1' COMMENT '账户状态',

    `is_delete` tinyint(1) DEFAULT '0' COMMENT '是否删除 1删除 0未删除',

    `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '最后修改时间',

    `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '添加时间',

    PRIMARY KEY (`id`) USING BTREE,

    UNIQUE KEY `username` (`website_id`,`account`,`password`) USING BTREE

    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

    ------------------------------

    -- toadmin_auth_log 操作日志,

    ------------------------------

    DROP TABLE IF EXISTS `toadmin_auth_log`;

    CREATE TABLE `toadmin_auth_log` (

    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id',

    `website_id` int(10) NOT NULL DEFAULT '0' COMMENT '站点id,用于多站点,默认0',

    `userid` varchar(50) NOT NULL COMMENT '用户账号',

    `name` varchar(255) DEFAULT NULL COMMENT '用户名',

    `source` varchar(255) NOT NULL COMMENT '来源',

    `route` varchar(100) DEFAULT NULL COMMENT '路由',

    `operation` varchar(255) DEFAULT NULL COMMENT '动作',

    `param` json DEFAULT NULL COMMENT '请求参数',

    `ip` varchar(16) DEFAULT NULL COMMENT 'ip',

    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

    PRIMARY KEY (`id`) USING BTREE,

    KEY `userid` (`website_id`,`userid`) USING BTREE

    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

    中间件验证使用,中间件

    ric\auth\middleware\Auth::class

    可以在config/middleware.php 中添加一条别名记录

    'auth' => ric\auth\middleware\Auth::class,

    例如路由:

    Route::get('/', 'index/controller/Index/index');

    使用后为:

    Route::get('/', 'index/controller/Index/index')->middleware(auth,['admin','login']);

    第一个参数:必填参数,用于标示是调用哪个端,对应config/auth.php 配置中的一维键

    第二个参数:选填,用于标示是否使用auth权限验证或者登录退出,login登录、logout退出、getinfo获取登录用户信息、log记录日志信息、getrule获取所有权限列表

    其中,login、logout成功时,会自动记录日志信息,其它需要配置第二个参数时才会记录日志信息到toadmin_auth_log表

    内置方法

    本包内置了,用户、权限、用户组等增删改查方法,详情查看 /vendor/ric/thinkphp6-auth/Auth.php类

    如:获取用户组:

    /**

    * 用户组列表

    */

    public function getGroupAll($current_page,$per_page)

    {

    $list = Db::table($this->config['auth_group'])

    ->where([])->withoutField('password')->paginate([

    'list_rows'=> $per_page?:10, //每页数量

    'var_page' => 'page', //分页变量

    'page' => $current_page?:1, //当前页面

    ]);

    return $list->toArray();

    }

    在路由中例子为:

    Route::post('auth/getGroupAll', 'Auth/getGroupAll')->middleware('auth',['admin']);

    在自己控制器中的调用方式例子为:

    /**

    * @title 获取用户组列表

    * @desc 用户组列表

    * @author Ric

    * @version 1.0

    *

    * @param int $current_page 1 分页数,指定获取第几页的数据 require_分页数不能为空.number

    * @param int $per_page 10 分页大小,指定分页大小 require_分页大小不能为空.number

    *

    * @return int id 1212

    * @return int website_id 445 站点id,用于多站点,默认0

    * @return char title 55 用户组中文名称

    * @return tinyint status 473 状态:为1正常,为0禁用

    * @return varchar rules 579 用户组拥有的规则id, 多个规则","隔开

    * @return datetime create_time 255 最后修改时间

    * @return datetime update_time 533 添加时间

    */

    public function getGroupAll()

    {

    //获取参数

    $data = request()->param();

    $list = request()->middleware('auth')->getGroupAll($data['current_page'], $data['per_page']);

    return totrue($list);

    }

    通过request()->middleware('auth') 来直接调用该包的类

    建议

    toadmin_auth_rule 中规则按页面结构进行创建,共用的部分统一放base中

    比如

    base 系统共用

    -- 上传

    website 站点管理页面,一级菜单

    -- 查看信息 查看站点信息

    -- 修改信息 修改站点信息

    -- 添加信息 添加站点信息

    通过中间件定义,可以获得用户所属的所有用户组,方便我们在网站上面显示。

    Auth类还可以按用户属性进行判断权限, 比如

    按照用户积分进行判断, 假设我们的用户表 (admin_members) 有字段 score 记录了用户积分。

    我在规则表添加规则时,定义规则表的condition 字段,condition字段是规则条件,默认为空 表示没有附加条件,用户组中只有规则 就通过认证。

    如果定义了 condition字段,用户组中有规则不一定能通过认证,程序还会判断是否满足附加条件。

    比如我们添加几条规则:

    name字段:grade1 condition字段:{score}<100

    name字段:grade2 condition字段:{score}>100 and {score}<200

    name字段:grade3 condition字段:{score}>200 and {score}<300

    这里 {score} 表示 admin_members 表 中字段 score 的值。

    那么这时候

    $auth->check('grade1', uid) 是判断用户积分是不是0-100

    $auth->check('grade2', uid) 判断用户积分是不是在100-200

    $auth->check('grade3', uid) 判断用户积分是不是在200-300

    json返回说明

    该应用内置了两个json输出函数,通过这两个函数可以输出统一格式的json,格式如下:

    {

    "status": '状态码',

    "message": "消息提示",

    "data": '数据内容'

    }

    /**

    * 返回json信息

    * @param string $status 当前错误状态

    * @param string $message 返回错误信息前追加内容,默认为空

    */

    function tofalse($status,$message=''){

    try {

    $data = tocode(100,$e->getMessage());

    return json($data);

    } catch (\Exception $e) {

    return json(tocode(-1,$e->getMessage()));

    }

    }

    /**

    * 返回操作成功json信息

    * @param array $object 当前返回对象

    * @param string $special 特殊返回对象处理 有类型:select

    */

    function totrue($object,$message=''){

    try {

    $data = tocode(100,$e->getMessage());

    $data['data'] = $object;

    ob_clean();

    return json($data);

    } catch (\Exception $e) {

    return json(tocode(-1,$e->getMessage()));

    }

    }

    api、rpc函数说明

    thinkphp6 取消了action 跨应用调用类,rpc函数即为该函数的替代品,可以实现,跨应用、跨目录调用

    例:

    rpc: 第一个参数为类名,填写完整的,方便ide调整,第二个参数为方法名,第三个参数为传值

    $isexist= rpc('app\admin\logic\authadmin\UserLogic', 'exist_account', [$account]);

    api: 第一个参数为类名,第一个参数为传值,其中$data 数据是对应形式,键和api文件定义的需要一直,会根据api文件

    的定义自动做数据效验。

    $data = [

    'website_id' => $website_id,

    ];

    $webinfo = api('app\website\api\config\Info',$data);

    app\website\api\config\Info.php 文件例子

    namespace app\website\api\config;

    use think\Validate;

    final class Info extends Validate

    {

    public $apiDescription = '获取站点配置详情';

    //API字段表,调用时,会自动根据这个设置来进行数据验证

    public $params = [

    'website_id' => ['valid'=>'require.站点ID不能为空|number', 'title'=>'站点id', 'desc'=>'用于区分站点'],

    ];

    //处理数据,创建验证器

    public function __construct(){

    list($this->rule,$this->message) = getValidate($this->params);

    parent::__construct();

    }

    /**

    * 详情,其中参数名称要和$params中定义的一致

    */

    public function api($website_id)

    {

    return rpc('app\website\logic\WebConfig', 'getWebConfigFind', [$website_id]);

    }

    }

    在开发时,建议采用领域应用模式开发,即每个应用,通过api提供接口,对其它应用对接,然后api接口通过rpc方法处理

    内部领域内容,一个应用即为一个领域。博主的目录结构如下,仅供参考:

    app

    -- website 站点管理应用 (该应用提供站点管理服务,对平台内部,不设置路由,不直接对外提供接口,核心api、logic、dao三层)

    -- api 对平台提供api服务,通过rpc调用自身的logic和dao层,进行业务处理,一个文件即一个接口

    -- config 站点配置信息

    -- Add.php 添加站点配置信息

    -- Info.php 获取站点配置信息

    -- logic 业务处理

    -- dao 数据处理

    -- toadmin 后台平台api (该应用为后台平台提供api接口,设置路由,供前端调用,编写页面,核心controller,无其它)

    -- controller 控制器,根据需要通过api函数调用 website站点的api 接口,获取信息,返回数据

    -- topc pc端平台api (该应用为pc端提供api接口,设置路由,供前端调用,编写页面,核心controller,无其它)

    -- controller 控制器,根据需要通过api函数调用 website站点的api 接口,获取信息,返回数据

    说明

    为啥api是一个接口一个文件嗯?

    1、方便管理

    2、后续会提供自动生产api文档,避免通用的功能不同人,或者时间久了维护时,拼命的写相同功能的方法,导致方法冗余严重,越来越难维护

    3、为后续其它应用做准备

    更新日志

    20210313 v1.0.39

    升级多website模式下,路由权限表需要重复复制填写问题,适用bbc网站,商家端等类似场景,配置项实现

    20200706 v1.0.35

    升级了登陆接口,可进行中间件进行小程序自动登陆

    20191012 v1.0.31

    中间件调整,src/middleware/Auth.php中31行,获取站点字段参数由website_id调整为base_website_id,以及获取参数与获取中间件调换位置。

    20190912 v1.0.7

    更新TP6 升级session导致的部分方法失效问题

    展开全文
  • 43.Django权限系统auth模块详解

    万次阅读 多人点赞 2021-09-10 08:05:19
      如上图就是Django自带的auth系统对应的表,也就是存放了之前创建的超级用户信息的表(也也就是之前没有提及到的数据库迁移生成的表~) 注意点:上面所示表中有多对多表关系生成的中间表,而Django很人性化的...

    昨天我们为了登录admin,通过命令创建了超级用户,你是不是有个疑问——这创建的超级用户的信息是存放在哪里了呢?
      这就想到了我们映射数据库时,Django自动创建的一些表(这也是之前进行数据库迁移时没有提到的那些表)!!!

    0.初接触

    在这里插入图片描述

      如上图就是Django自带的auth系统对应的表,也就是存放了之前创建的超级用户信息的表(也也就是之前没有提及到的数据库迁移生成的表~)

    注意点:上面所示表中有多对多表关系生成的中间表,而Django很人性化的一点是:如果是多对多关系产生的中间表,其命名方式是主表在前,从表在后!比如auth_group_permissions表,其中auth_group就是主表,auth_permissions就是从表,如果要进行两表关联,则从auth_group到auth_permissions是正向!!!

    从上图表的名称我们就能看出,
    auth_user,auth_group,auth_permission分别
    存放了用户,用户组,权限的信息表.
    另外三张表就是多对多关系的中间表

    1.Django权限系统auth模块

    • auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理这些功能,那么我们就可以使用它来完善我们之前的一些小型项目;

    • auth可以和admin模块配合使用, 快速建立网站的管理系统;

    • 在INSTALLED_APPS中添加’django.contrib.auth’使用该APP, auth模块默认启用。

    1. User:User是auth模块中维护用户信息的关系模式(继承了models.Model), 数据库中该表被命名为auth_user(上篇文中创建的超级用户信息就存储在此表中哦!)。
    2. Group:User对象中有一个名为groups的多对多字段, 多对多关系由auth_user_groups数据表维护。Group对象可以通过user_set反向查询用户组中的用户。
    3. Permission:Django的auth系统提供了模型级的权限控制, 即可以检查用户是否对某个数据表拥有增(add), 改(change), 删(delete)权限。

    2.Django权限系统auth模块中的——User模型

    (1)User表的SQL描述:

    在这里插入图片描述
    (我们可以查看此表,发现之前创建的超级用户信息就在这哦!不过密码是经过HASH加密了~)
    在这里插入图片描述

    • User对象顾名思义即为表示用户的对象,里面的属性包括以上几条:

    • 创建好对象后,django会自动生成表,表名为auth_user,包含以上字段。

    • User模型常用属性和方法如下:

    username用户名。必选。少于等于30个字符。 用户名可以包含字母、数字、_、@、+、.和- 字符。
    first_name可选。 少于等于30个字符。
    last_name可选。少于30个字符。
    email可选。邮箱地址。
    password必选。 密码的哈希及元数据。(Django 不保存原始密码)。原始密码可以无限长而且可以包含任意字符。参见密码相关的文档。
    groups与Group 之间的多对多关系。
    user_permissions与Permission 之间的多对多关系。
    is_staff布尔值。指示用户是否可以访问Admin 站点(即是否是admin的管理员)。
    is_active布尔值。指示用户的账号是否激活。
    is_superuser布尔值。是否是超级用户。
    last_login用户最后一次登录的时间。
    date_joined账户创建的时间。当账号创建时,默认设置为当前的date/time。
    is_authenticated
    is_anonymous
    set_password(raw_password)
    check_password(raw_password)
    has_perm(perm)
    has_perms(perm_list)

    (2)auth模块提供了很多API管理用户信息, 在有相关需求的时候我们可以导入User表进行操作,下面详细讲解auth认证系统的几大常用功能:

    from django.contrib.auth.models import User
    

    ①创建用户:

     User.objects.create_user(username, email, password)
    

    (比如前面的注册登录小案例,我们可以通过更改入库的代码,来实现user用户的创建~)

    在这里插入图片描述

    ②认证用户:

    因为创建的user用户的password是加密之后入库的,无法直接对比来判断用户是否存在,所以Django就自带了authenticate函数来进行用户认证。

    1. 导入所用函数:
    from django.contrib.auth import authenticate
    
    1. 使用:
    user = authenticate(username=username, password=password)
    

    认证用户的密码是否有效, 若有效则返回代表该用户的user对象, 若无效则返回None(注意:该方法不检查is_active标志位.)

    (比如前面的注册登录小案例,我们可以通过更改原本查询的代码,来实现user用户的认证~)
    在这里插入图片描述

    补充:现在前端验证是否登录的话直接user.username获取即可!(如果登录则会获取到登录的用户的名字;未登录则获取不到。)

    在这里插入图片描述

    ③登录:

    1. 导入所用函数:
    from django.contrib.auth import login
    
    1. 使用(login向session中添加SESSION_KEY, 便于对用户进行跟踪):
    login(request, user)
    

    注意——login不进行认证,也不检查is_active标志位, 所以一般和authenticate配合使用:

    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
    

    (比如前面的注册登录小案例,我们可以通过更改原本设置session的代码,来实现登录~)
    在这里插入图片描述

    ④登出:

    1. 导入所用函数:
    from django.contrib.auth import logout
    
    1. 使用(logout会移除request中的user信息, 并刷新session):

    在这里插入图片描述

    ⑤只允许登录的用户访问:

    • @login_required修饰器修饰的view函数会先通过session key检查是否登录, 已登录用户可以正常的执行操作, 未登录用户将被重定向到login_url指定的位置;

    • 若未指定login_url参数, 则重定向到settings.LOGIN_URL。

    1. 导入使用的函数:
    from django.contrib.auth.decorators import login_required
    
    1. 使用:
    @login_required(login_url='/accounts/login/')
    def my_view(request):
        ...
    

    按照常规逻辑来说——你没登录,网站给你跳转到登录页面要求你登录,那么在你登录之后应该再给你跳转回去之前的页面。下面来带你实现:

    我们使用⑤发现,比如我们未登录状态下访问一个页面,它会立马重定向到我们指定的登录页面。
    现在有个需求,我们在登录之后,能够让页面回到我们先前访问的那个页面。观察URL发现,跳转到登录页面的URL里携带一个参数next,值为跳转的源路径。所以获取一下即可!
    在这里插入图片描述
    (比如前面的注册登录小案例,我们只需要在登录业务逻辑中进行判断,如果可以获取到index参数,那就说明我们是因为权限不够没有登录而跳转过来的;如果获取不到Index参数,那就说明我们是正常登录!)

    在这里插入图片描述

    ⑥判断用户是否登录:

    is_authenticated
    

    通过在视图函数中利用User对象的is_authenticated方法进行判断用户是否登录。如:

    在这里插入图片描述

    3.Django权限系统auth模块中的——Group模型

    django.contrib.auth.models.Group定义了用户组的模型, 每个用户组拥有id和name两个字段, 该模型在数据库被映射为auth_group数据表。
    在这里插入图片描述
    User对象中有一个名为groups的多对多字段, 多对多关系由auth_user_groups数据表维护。Group对象可以通过user_set反向查询用户组中的用户。

    我们可以通过创建删除Group对象来添加或删除用户组:

    导入使用的函数:

    from django.contrib.auth.models import Group 
    

    (1)添加用户组——add

    group = Group.objects.create(name=group_name)
    group.save()
    

    (2)删除用户组——del

    group.delete()
    

    我们可以通过标准的多对多字段操作管理用户与用户组的关系:

    注意:下述的user是获取到的user实例,group也是获取到的group实例。比如:
    user = User.objects.get(id=1)
    group = Group.objects.get(id=1)

    • 用户加入用户组:user.groups.add(group)或group.user_set.add(user)

    • 用户退出用户组:user.groups.remove(group)或group.user_set.remove(user)

    • 用户退出所有用户组:user.groups.clear()

    • 用户组中所有用户退出组:group.user_set.clear()

    4.Django权限系统auth模块中的——Permission模型

    Django的auth系统提供了模型级的权限控制, 即可以检查用户是否对某个数据表拥有增(add), 改(change), 删(delete)权限。

    auth系统无法提供对象级的权限控制, 即检查用户是否对数据表中某条记录拥有增改删的权限。如果需要对象级权限控制可以使用django-guardian。假设在博客系统中有一张article数据表管理博文, auth可以检查某个用户是否拥有对所有博文的管理权限, 但无法检查用户对某一篇博文是否拥有管理权限。

    查看数据库中auth_permission这张表,在里面有所有的表的一些操作权限,这些是在表创建的同是添加进来的数据(你会发现对应表的权限的名字是由其模型类名构成的!)

    在这里插入图片描述
    知识补给站:

    1. 每个模型默认拥有增(add), 改(change), 删(delete)权限。在django.contrib.auth.models.Permission模型中保存了项目中所有权限。

    2. 该模型在数据库中被保存为auth_permission数据表。每条权限拥有id ,name , content_type_id, codename四个字段。

    ①检查用户权限:

    user.has_perm方法用于检查用户是否拥有操作某个模型的权限:

    user.has_perm(‘blog.add_article’)
    user.has_perm(‘blog.change_article’)
    user.has_perm(‘blog.delete_article’)

    • 上述语句检查用户是否拥有blog这个app中article模型的添加权限, 若拥有权限则返回True。

    • has_perm仅是进行权限检查, 即用户没有权限它也不会阻止用户执行相关操作。

    ②permission_required装饰器——设置权限:

    permission_required修饰器可以代替has_perm并在用户没有相应权限时重定向到登录页或者抛出异常。

    @permission_required(appname.codename(权限名称))
    给名为blog的app当中的博客添加视图设置权限:

    from django.contrib.auth.decorators import permission_required
    
    @permission_required('blog.add_blogmodel')		# 给对应的视图设置权限,让除了超级用户之外的用户丧失设置的权限!可以依此方法设置任意四种权限!
    def add_get_post(request):
    	...
    

    这样的话只有被设置拥有此权限的用户才可访问此视图函数对应的前端页面(注意:如果是超级用户是拥有所有权限的)。

    哪怕你登录了普通用户会发现也访问失败,它会自动给你跳转到你settings.py文件中设置的权限不足而跳转到的页面里!(此处为登录页面。)

    在这里插入图片描述

    ③管理用户权限——单用户管理&&分组管理:

    第一个:单用户管理!

    User和Permission通过多对多字段user.user_permissions关联,在数据库中由auth_user_user_permissions数据表维护。

    • 添加权限: user.user_permissions.add(permission)

    • 删除权限: user.user_permissions.delete(permission)

    • 清空权限: user.user_permissions.clear()

    实战使用——给指定用户添加权限(直接在前面的博客小案例上操作):

    通过观察auth_permission权限表可知:如果你要给指定用户添加某个权限,那实现的方法就是通过用户信息表auth_user和权限信息表auth_permissons由于多对多关系产生的中间表auth_user_user_permissions的操作来完成,即让指定的用户与要添加的权限产生关系!(多对多表关系的添加)

    ①注意:要导入权限表!
    在这里插入图片描述

    ②图个方便,直接找个视图在里面进行操作:
    在这里插入图片描述

    ③现在如果访问博客添加页面,哪怕你登录了普通用户(id为1)会发现也可以访问,这就说明咱给这个普通用户成功添加了添加权限!

    第二个:分组管理!

    用户拥有他所在用户组的权限, 使用用户组管理权限是一个更方便的方法。Group中包含多对多字段permissions, 在数据库中由auth_group_permissions数据表维护。

    • 添加权限: group.permissions.add(permission)

    • 删除权限: group.permissions.delete(permission)

    • 清空权限: group.permissions.clear()

    实战使用——给组添加权限(直接在前面的博客小案例上操作):

    如何理解?试想上面给少数用户添加权限不是很麻烦,但是如果要给好多的用户添加权限岂不是很麻烦,所以又了给组添加权限的概念。我们可以将删除权限设置成一个组;查看权限设置成一个组…如果来了几十个需要添加查看权限的用户,只需将它们都扔进查看权限那个组即可!而且如果以后要对拥有查看权限的用户的权限进行改动或者升级,这样也非常方便!

    组信息表的结构:

    在这里插入图片描述

    ①注意:导入组信息表
    在这里插入图片描述

    ②通过观察组信息表的结构创建组:

    在这里插入图片描述
    在这里插入图片描述
    ③为新创建的组添加权限(此处是添加了添加权限!):

    在这里插入图片描述

    ④举例将一个用户扔进组中,说明如何将用户放进具有权限的组中:
    在这里插入图片描述

    ⑤现在如果访问博客添加页面,哪怕你登录了普通用户(id为3)会发现也可以访问,这就说明咱给这个普通用户成功添加了添加权限!

    展开全文
  • Laravel 用户认证 Auth

    2021-04-22 06:59:40
    很多应用是需要登陆后才能...大概看一下auth工具的常用方法Auth::check();// 判断当前用户是否未登录Auth::guest();// 判断当前用户是否未登录,与 check() 相反Auth::guard();// 自定义看守器 默认为 `web`Auth::us...

    很多应用是需要登陆后才能操作,Laravel提供了一个auth工具来实现用户的认证功能。并且有一个config/auth.php来配置auth工具。大概看一下auth工具的常用方法

    Auth::check();// 判断当前用户是否未登录

    Auth::guest();// 判断当前用户是否未登录,与 check() 相反

    Auth::guard();// 自定义看守器 默认为 `web`

    Auth::user();// 获取当前的认证用户,一个提供者的模型

    Auth::id();// 获取当前的认证用户的 ID(未登录情况下会报错)

    Auth::attempt(['email' => $email, 'password' => $password],true);// 通过给定的信息来尝试对用户进行认证(成功后会自动启动会话),第一个数组就是认证的参数,第二个参数true就是'记住我'功能

    Auth::login(User::find(1), $remember = false);// 登录一个指定用户到应用上,一般是登陆的参数通过后,执行login方法,保存session等登陆成功的操作

    Auth::logout();// 使用户退出登录(清除会话)

    看一下auth.php的配置,其实Auth的实现原理就是通过一个guard来实现的

    'defaults' => [

    'guard' => 'web', //没有指定guard时,就用‘web’

    'passwords' => 'users',

    ],

    'guards' => [ //这就是guard数组,用哪一个guard需要指定

    'web' => [

    'driver' => 'session',

    'provider' => 'users',

    ],

    'api' => [

    'driver' => 'token',

    'provider' => 'users',

    'hash' => false,

    ],

    ],

    //每一个guard最少需要两个成员,driver驱动(比如登陆成功,通过什么方式保存登陆状态),provider提供者(就是用户表,保存用户名密码的那张表)

    所以一个系统中,我们可以有多个认证体系,前后台认证,接口认证等等,只要配置不同的guard即可。不同认证体系,使用对应的guard就可以。

    说了这么多,还是很懵逼,不怕,laravel给我们实现一个客户认证脚手架,通过命令就可以实现一套认证系统。我们把这套系统弄懂,就可以仿照它的体系生成我们自己的认证体系。

    laravel脚手架实现认证体系

    php artisan make:auth

    这个命令会做哪些动作?

    1.生成登陆,注册,退出等等的路由,在web.php新增Auth::routes();等价于下面

    public function auth(array $options = [])

    {

    // Authentication Routes...

    $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');

    $this->post('login', 'Auth\LoginController@login');

    $this->post('logout', 'Auth\LoginController@logout')->name('logout');

    // Registration Routes...

    if ($options['register'] ?? true) {

    $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');

    $this->post('register', 'Auth\RegisterController@register');

    }

    // Password Reset Routes...

    if ($options['reset'] ?? true) {

    $this->resetPassword();

    }

    // Email Verification Routes...

    if ($options['verify'] ?? false) {

    $this->emailVerification();

    }

    }

    其实就到调用Router::auth(),我们就可以看到登陆注册的路由啦,其他功能类似。

    2.生成登陆注册等控制器App\Http\Controllers\Auth目录下面,上面的路由就是访问这里的控制器

    3.生成登陆注册等页面resource/views/auth/目录下

    4.生成provider表的migerate,创建用户表,这时候你可以修改这个用户表字段

    public function up()

    {

    Schema::create('users', function (Blueprint $table) {

    $table->bigIncrements('id');

    $table->string('name');

    $table->string('email')->unique();

    $table->timestamp('email_verified_at')->nullable();

    $table->string('password');

    $table->rememberToken();

    $table->timestamps();

    });

    }

    php artisan migrate//生成user表

    这样,访问上面的路由就可以生成一套认证体系了。认证系统其实就是三个步骤

    1.登陆注册等逻辑接口,就是控制器

    2.配置路由

    3.页面

    脚手架认证体系原理,我们自定义认证体系

    先看注册的逻辑,我们自定义自己的注册类的时候,也可以参考着写,跳转路径,检查字段,用户表都可以根据实际情况修改。而接口,laravel已经写在RegistersUsers里面了。

    class RegisterController extends Controller

    {

    use RegistersUsers; //这个是laravel写好的trait

    protected $redirectTo = '/home';//注册成功跳转路径

    public function __construct()

    {

    $this->middleware('guest');//添加一个guest中间件

    }

    protected function validator(array $data)

    {

    return Validator::make($data, [ //返回一个过滤器

    'name' => ['required', 'string', 'max:255'],

    'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],

    'password' => ['required', 'string', 'min:8', 'confirmed'],

    ]);

    }

    protected function create(array $data)

    {

    return User::create([ //注册最终会写入到provider中,通过create插入数据,返回模型

    'name' => $data['name'],

    'email' => $data['email'],

    'password' => Hash::make($data['password']),

    ]);

    }

    protected function guard()//这个方法trait也有,但是如果我们用其他的guard,就要重写方法

    {

    return Auth::guard('api');//你要使用的guard

    }

    }

    但是还是要看一下laravel是怎么通过auth和auth的配置来实现注册的

    public function register(Request $request)

    {

    $this->validator($request->all())->validate();//判断参数

    event(new Registered($user = $this->create($request->all())));//注意看create方法,这是插入到用户表中,返回那个模型。

    $this->guard()->login($user);//获取对应的guard,执行login方法,其实就是告诉session这个用户登录成功状态。(注册成功,就不用重新登录),具体流程下面登录成功的操作再分析

    return $this->registered($request, $user)

    ?: redirect($this->redirectPath());//注册成功跳转

    }

    其实注册步骤还是非常简单的,参数正确,就可以写入用户表,注册成功,然后跳转。

    登录逻辑

    class LoginController extends Controller

    {

    use AuthenticatesUsers;

    protected $redirectTo = '/home';//登录成功跳转路径

    public function __construct()

    {

    $this->middleware('guest')->except('logout');//添加guest中间件,除了logout方法

    }

    protected function guard()//这个方法trait也有,但是如果我们用其他的guard,就要重写方法

    {

    return Auth::guard('api');//你要使用的guard

    }

    }

    登录接口laravel也帮我们实现了,直接use AuthenticatesUsers.我们看看

    public function login(Request $request)

    {

    $this->validateLogin($request);//验证参数

    if ($this->hasTooManyLoginAttempts($request)) {//登录失败次数,超过次数不能再登陆

    $this->fireLockoutEvent($request);

    return $this->sendLockoutResponse($request);

    }

    if ($this->attemptLogin($request)) { //比对数据库,看看登陆是否成功

    return $this->sendLoginResponse($request);

    }

    $this->incrementLoginAttempts($request);//增加登陆失败次数,以$this->username())),$request->ip()为基准,就是说同一个username,同一个ip登陆失败次数是有限的。时间是1h.

    return $this->sendFailedLoginResponse($request);

    }

    我们主要看他如何查用户表,如何判断登录是否成功

    protected function attemptLogin(Request $request)

    {

    return $this->guard()->attempt(

    $this->credentials($request), $request->filled('remember')

    );

    }

    和注册一样,也是获取到对应的guard配置的Auth,执行attempt方法来验证,所以不同的guard就要重写guard方法,才能配置Auth.

    Auth门面介绍

    其实操作的类是Illuminate\Auth\AuthManager,而最终功能其实是对应的driver类实现的。

    Auth::guard('web'),返回一个对象,就是那个driver对象

    public function guard($name = null)

    {

    $name = $name ?: $this->getDefaultDriver();

    return $this->guards[$name] ?? $this->guards[$name] = $this->resolve($name);

    }

    protected function resolve($name)

    {

    $config = $this->getConfig($name);

    if (is_null($config)) {

    throw new InvalidArgumentException("Auth guard [{$name}] is not defined.");

    }

    if (isset($this->customCreators[$config['driver']])) {

    return $this->callCustomCreator($name, $config);

    }

    $driverMethod = 'create'.ucfirst($config['driver']).'Driver';

    if (method_exists($this, $driverMethod)) {

    return $this->{$driverMethod}($name, $config);

    }

    throw new InvalidArgumentException(

    "Auth driver [{$config['driver']}] for guard [{$name}] is not defined."

    );

    }

    需要说明的,laravel给我们配置了三种guard的driver,分别是session,token,request,都放在Illuminate\Auth目录下,先看一下SessionGuard

    public function __construct($name,UserProvider $provider,Session $session,Request rquest = null)

    {

    $this->name = $name;

    $this->session = $session;//操作session的工具

    $this->request = $request;//request

    $this->provider = $provider;//就是我们的provider模型

    }

    有了这三个工具,我们就可以实现auth的各种功能了。

    比如登陆attempt()

    public function attempt(array $credentials = [], $remember = false)

    {

    $this->fireAttemptEvent($credentials, $remember);

    //用除了密码查询provider表,得到$user。

    $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);

    //对比密码是否正确

    if ($this->hasValidCredentials($user, $credentials)) {//严重

    $this->login($user, $remember);//成功就执行login方法

    return true;

    }

    $this->fireFailedEvent($user, $credentials);

    return false;

    }

    比如获取登陆的客户模型Auth::user();

    public function user()

    {

    if ($this->loggedOut) {

    return;

    }

    if (! is_null($this->user)) {

    return $this->user;

    }

    $id = $this->session->get($this->getName());//通过session获取id

    if (! is_null($id) && $this->user = $this->provider->retrieveById($id)) {

    $this->fireAuthenticatedEvent($this->user);

    }

    if (is_null($this->user) && ! is_null($recaller = $this->recaller())) {

    $this->user = $this->userFromRecaller($recaller);

    if ($this->user) {

    $this->updateSession($this->user->getAuthIdentifier());

    $this->fireLoginEvent($this->user, true);

    }

    }

    return $this->user;

    }

    在看看TokenGuard,就是登陆成功会给前端保存一个token,每次请求要带这个token

    Auth::user();

    public function user()

    {

    // If we've already retrieved the user for the current request we can just

    // return it back immediately. We do not want to fetch the user data on

    // every call to this method because that would be tremendously slow.

    if (! is_null($this->user)) {

    return $this->user;

    }

    $user = null;

    $token = $this->getTokenForRequest();//从request得到token值

    if (! empty($token)) {

    $user = $this->provider->retrieveByCredentials([

    $this->storageKey => $this->hash ? hash('sha256', $token) : $token,

    ]);

    }

    return $this->user = $user;

    }

    $this->storageKey 默认是"api_token",所以查询provider表的条件是['api_token'=>$token],我们的用户表需要一个api_token字段保存登陆的token值。

    Auth中间件验证登陆

    我们知道,要让接口通过登陆验证才能访问,需要在添加auth中间件,这个laravel已经配置好了

    protected $routeMiddleware = [

    'auth' => \App\Http\Middleware\Authenticate::class,//系统生成的前台登陆验证

    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,

    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,

    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,

    'can' => \Illuminate\Auth\Middleware\Authorize::class,

    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,

    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,

    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,

    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,

    'auth.admin' => \App\Http\Middleware\AdminAuthMiddleware::class,// 后台登陆验证

    ];

    这个Authenticate中间件继承了Illuminate\Auth\Middleware\Authenticate类

    看它的handle方法

    public function handle($request, Closure $next, ...$guards)

    {

    $this->authenticate($request, $guards);

    return $next($request);

    }

    protected function authenticate($request, array $guards)

    {

    if (empty($guards)) {

    $guards = [null];

    }

    foreach ($guards as $guard) {

    if ($this->auth->guard($guard)->check()) { //Auth::check方法验证

    return $this->auth->shouldUse($guard);

    }

    }

    throw new AuthenticationException(

    'Unauthenticated.', $guards, $this->redirectTo($request)

    );

    }

    自定义后台验证如何配置验证中间件

    比如我们建了一套后台的登陆验证系统,使用的guards是admin,我们的后台路由就需要一个中间件来验证登陆了

    php artisan make:middleware AdminAuth

    把中间件写入到路由中间件数组中

    protected $routeMiddleware = [

    'auth' => \App\Http\Middleware\Authenticate::class,//系统生成的前台登陆验证

    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,

    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,

    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,

    'can' => \Illuminate\Auth\Middleware\Authorize::class,

    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,

    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,

    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,

    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,

    'auth.admin' => \App\Http\Middleware\AdminAuthMiddleware::class,// 后台登陆验证

    ];

    中间件的过滤代码

    public function handle($request, Closure $next, $guard = null)

    {

    //当 auth 中间件判定某个用户未认证,会返回一个 JSON 401 响应,或者,如果是 Ajax 请求的话,将用户重定向到 login 命名路由(也就是登录页面)。

    if (Auth::guard($guard)->guest()) {

    if ($request->ajax() || $request->wantsJson()) {

    return response('Unauthorized.', 401);

    } else {

    return redirect()->guest('admin/login');

    }

    }

    return $next($request);

    }

    这里中间件需要传一个参数$guard,不传就是web,所以说中间件的guard要和我们的登陆,注册等系列接口要保持一致。假如我们创建了一个admin的guard,路由就应该这样写

    // 后台其他页面都要有登陆验证

    Route::middleware('auth.admin:admin')->name('admin.')->group(function () {

    //后台的其他路由

    }

    本作品采用《CC 协议》,转载必须注明作者和本文链接

    用过哪些工具?为啥用这个工具(速度快,支持高并发...)?底层如何实现的?

    展开全文
  • Django Auth 登录认证

    2021-11-17 16:43:21
    一、Auth 模块介绍 用户模型:用户认证、登录、退出等 后台管理:用户管理、权限分配 1.1 安装与配置 # INSTALLED_APPS 安装应用 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib....

    一、Auth 模块介绍

    • 用户模型:用户认证、登录、退出等
    • 后台管理:用户管理、权限分配
    • Django自带一个用户认证系统,用于处理账号、组、权限以及基于Cookie的用户会话

    1.1 安装与配置

    # 通常已自带
    # INSTALLED_APPS 安装应用
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    # MIDDLEWARE 中间件配置
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # 数据库迁移命令
    # 自己在命令行中执行:
    python manage.py makemigrations
    python manage.py migrate
    

    1.2 Auth 用户类型

    • 注册用户(User),超级用户,普通用户
    • 游客(AnonymousUser)

    1.3 Auth 常用字段含义

    序号字段说明
    1username用户名
    2password登录密码
    3email邮箱
    4first_name
    5last_name
    6is_superuser是否是超级管理员账号/admin
    7is_staff是否可以访问admin管理后台
    8is_active是否是活跃用户,默认为True,一般不删除,而是将用用户的is_active设置为False
    9is_authenticated用户是否已登录的只读属性
    10is_anonymous用户是否登录失效的只读属性
    11date_joined用户创建的时间
    12last_login上一次登录时间
    13groups用户组多对多关系
    14user_permission用户权限多对多关系

    二、Auth 用户信息管理

    官网参考地址:https://docs.djangoproject.com/zh-hans/3.2/topics/auth/default/#user-objects

    2.1 创建用户

    • 创建普通用户
    from django.contrib.auth.models import User
    # 只有usename是必填项,其余可不填
    # 创建密码为明文密码的普通用户
    User.objects.create(username="AA",password="123")
    # 创建密码为通过Django内部自动加密的密码的普通用户
    User.objects.create_user(username="AA",password="123")
    
    • 创建超级用户
    from django.contrib.auth.models import User
    # 只有usename是必填项,其余可不填
    User.objects.create_superuser(username="AA",password="123")
    

    2.2 删除用户

    建议使用:伪删除,即将is_active修改为False

    from django.contrib.auth.models import User
    
    try:
        user = User.objects.get(username = "用户名")
        user.is_ active = False 
        user.save()
        print("删除用户成功")
    except:
        print("删除用户失败,或该用户不存在")
    

    注意: 不可用update来更新,User不能用。

    user = User.objects.get(username = "用户名")
    user.update(is_active=True)
    """
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
    AttributeError: 'User' object has no attribute 'update'
    """
    

    2.3 密码管理

    • 修改密码
    >>> from django.contrib.auth.models import User
    >>> u = User.objects.get(username='john')
    >>> u.set_password('new password')
    >>> u.save()
    
    from django.contrib.auth.models import User
    
    try:
        user = User.objects.get(username="用户名")
        user.set_password("明文密码")
        user.save()
    	return HttpResponse("修改密码成功")
    except:
        return HttpResponse("修改密码失败")
    
    • 校验密码是否正确
    u = User.objects.get(username='aa')
    u.check_password('my password')
    

    三、Auth 登录校验

    3.1 authenticate 登录校验

    from django.contrib.auth import authenticate
    user = authenticate(username = username,password=password)
    

    说明: 若用户名密码校验成功则返回对应的user对象,否则返回None。

    from django.contrib.auth import authenticate
    user = authenticate(username="AA",password="123")
    # 正确输出
    user
    <User: AA>
    

    3.2 Auth 登录状态保持

    from django.contrib.auth import login
    from django.contrib.auth import authenticate
    
    def login_view(request):
        ...
        # 先校验
        user = authenticate(username="用户名",password="密码")
        ...
        # 检验成功则保持登录状态
        login(request,user) # 若用户通过检验,则可以调用此来保持登录状态
    

    注: 保存的方式为session,且时间不可以控制,当session什么时候过期,那么就什么时候断开。

    3.3 Auth 登录状态校验

    同前,用django自带登录状态校验装饰器,实现登录状态的校验。哪个视图需要,就放在哪个视图之前。

    • 未登录需要跳转地址,需要在settings.LOGIN_URL中设置
    import django.contrib.auth.decorators import login_required
    
    @login_required # 通过登录则返回下面视图,否则跳转至登录页面
    def index_view(request):
        # 该视图必须为用户登录状态下才能访问
        # 当前登录用户通过request.user获取
        login_user = request.user
        ...
    

    3.3 Auth 登录状态取消

    from django.contrib.auth import logout
    def logout(request):
        logout(request)
        # 请求传过来,然后将session清空,从而取消登录
    

    四、 基于Auth实现登录与注册

    • 引用的相关库
    # 用户模型
    from django.contrib.auth.models import User
    # 登录状态检验的装饰器
    from django.contrib.auth.decorators import login_required
    # 记录登录状态、退出登录状态、登录用户信息的校验
    from django.contrib.auth import login,logout,authenticate
    
    • 注册
    def reg_view(request):
        # 注册
        if request.method == "GET":
            return render(request,"reg_view")
        elif request.method == 'POST':
            username = request.POST.get("user")
            pwd1 = request.POST.get("pwd1")
            pwd2 = request.POST.get("pwd2")
            if not User.objects.filter(uesename=username):
                if pwd1 == pwd2:
                    # 这里可以try一下,因为用户名唯一性,可能会出现SQL唯一性异常报错
                    user = User.objects.create_user(username=username,password=pwd1)
                else:
                    return HttpResponse("密码不一致,请重新输入")
            else:
                return HttpResponse("该用户名已注册,请重新输入")
    
            # # 实现用户注册后免登录
            # login(request,user)
            # return HttpResponseRedirect("/index")
            return HttpResponseRedirect("/login")
    
    • 登录
    def login(request):
        if request.method == "GET":
            return render(request,"login.html")
        elif request.method == "POST":
            username = request.POST.get("username")
            password = request.POST.get("password")
            user = authenticate(username=username,password=password)
            if not user:
                # 用户名或密码错误
                return HttpResponse("用户名或密码错误")
            else:
                # 校验成功
                # 记录会话登录状态
                login(request,user)
                return HttpResponseRedirect("/index")
    
    • 退出
    def logout(request):
        logout(request)
        return HttpResponseRedirect("/login")
    
    • 首页
    # 需要登录状态检验才能访问的页面
    @login_required()
    def index_view(request):
        # 首页,必须登录才能访问,未登录跳转至settings.LOGIN_URL设置
        # 获取当前登录用户名
        user = request.user
        return render(request,"index.html")
    

    五、 扩展 Django 中的用户模型

    当我们要使用如手机号字段时,发现用户字段不够用,这时就需要想办法来增加字段。

    • 方案1:通过建立新表,与内建表做一对一验证
      • 应用时查询较麻烦
    • 方案2:继承内建的抽象User模型类
      • 继承现有的模型字段到一个新表,将我们的表告知Django将原User模型类替换为SelfUser模型类

    继承内建抽象类: 后台管理密码修改问题解决方案

    • step1:添加新应用
    • step2:定义模型类,继承AbstractUser
    # 所在位置:appname/models.py
    from django.db import models
    from django.contrib.auth.models import AbstractUser
    # Create your models here.
    
    class UserInfo(AbstractUser):
        # 在原有的基础上,添加一个手机号字段
        phone = models.CharField(max_length=11,default="")
    
    • step3:settings.py中指明AUTH_USER_MODDEL="应用名.类名"
    # 所在位置 mysite_name/settings.py
    AUTH_USER_MODEL = 'appname.UserInfo'
    
    • step4:最好在首次执行数据库迁移命令。

    注意: 此流程最好要在第一次migrate时执行,否则用方案1合适。后面一切调用模型类时就应该是UserInfo这个模型类了。

    –添加新用户–

    from user.models import UserInfo
    user = UserInfo(username="XX",password="xxxx",phone="xxxxxxxx")
    
    展开全文
  • 前言本文主要给大家介绍的是关于Laravel中Auth模块的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。本文是基于Laravel 5.4 版本的本地化模块代码进行分析书写;模块组成Auth模块从...
  • JAVAMAIL:AUTH NTLM失败

    2021-07-17 01:38:11
    250-SIZE 250-PIPELINING 250-DSN 250-ENHANCEDSTATUSCODES 250-STARTTLS 250-X-ANONYMOUSTLS 250-AUTH NTLM 250-X-EXPS GSSAPI NTLM 250-8BITMIME 250-BINARYMIME 250-CHUNKING 250-XEXCH50 250-XRDST 250 XSHADOW...
  • TP5之Auth权限管理实例

    2021-03-23 23:59:16
    权限管理是一个项目中必不可少的模块之一,常用的有RBAC、Auth等。本文就分享在TP5中通过Auth验证权限的实例,希望对大家有所帮助。
  • 文章目录Auth模块Auth模块的基本功能auth表的扩建 Auth模块 Auth模块 - Auth模块是Django自带的功能强大的用户认证模块. - Auth可以实现包括用户的注册, 登录, 注销, 认证, 密码管理等功能 - Auth用户认证系统...
  • FRI.Django 中的装饰器及 Auth 模块 CBV 装饰器 添加装饰器的三种方式 No.1 Scheme 指名道姓 from django.views import View from django.utils.decorators import method_decorator class MyLogin(View): @...
  • java发起Digest Auth请求

    2021-08-13 15:45:56
    主要逻辑: 1.通过HttpURLConnection建立连接 2.生成授权信息 3.建立通信,发起请求。如果返回401,继续下一次请求。重新设置响应,并获取随机数,通过md5加密返回 4.响应输出,转换未xml或者json ...
  • 准备工作CentOS7服务器,nginx源码包(笔者使用nginx1.12.0稳定版)支持nginx的编译环境,并安装有openssl开发包存在libmysqlclient以及libmysqld动态库安装流程记录nginx_auth_mysql的源代码文件如下所示:$...
  • fastadmin的权限管理auth

    千次阅读 2020-12-22 04:19:36
    fastadmin的权限管理auth <?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // +------------------------------------------...
  • 本文以实例代码的形式深入剖析了ThinkPHP权限认证Auth的实现原理与方法,具体步骤如下:sql;">-- ------------------------------ Table structure for think_auth_group-- ----------------------------DROP ...
  • ceph auth命令收集

    2021-11-11 21:29:56
    auth add <entity> {<caps> [<caps>...]} add auth info for <entity> from input file, or random key if no input is given, and/or any caps specified in the command auth caps <...
  • laravel8+tymon/jwt-auth搭建api系统

    千次阅读 热门讨论 2020-12-26 16:30:52
    配置文件 config/app.php5. 发布 Dingo 和 JWT 的配置文件1)发布配置文件2)修改配置文件3)修改 config/auth.php 配置文件6. 在 .env 中写入 Dingo 配置7.新增phone字段1)修改database/migrations/da2014_10_12_...
  • 来源:https://zhenbianshu.github.io文章介绍了spring-boot中实现通用auth的四种方式,包括传统AOP、拦截器、参数解析器和过滤器,并提供了对应的实例...
  • Auth fail

    2021-07-14 12:04:19
    Auth fail 原因:公钥不对。问题如果本地测试可以连接成功,springcloud连接失败,则是生成的问题。 原来的生成方式: ssh-keygen -t rsa -C yourname@your.com 改为: ssh-keygen -m PEM -t rsa -b 4096 -C your...
  • 在网站的登录验证逻辑中,为了好维护,一般后台会独立出来一个模块, 此时就不能和前台的模块混到一起去验证, 需要单独为后台指定一个guard(提供数据的)authlaravel 的Auth是由两个部分组成的后台登录 指定guard 不用...
  • JWT笔记(com.auth0)

    2021-04-21 15:52:30
    com.auth0 java-jwt 3.4.0 org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.3 org.projectlombok lombok 1.18.12 com.alibaba druid 1.1.19 mysql mysql-connector-java 5.1.38 2.编写配置...
  • 本文实例讲述了php使用Header函数,PHP_AUTH_PW和PHP_AUTH_USER做用户验证的方法。分享给大家供大家参考,具体如下:在php中,可以使用Header函数做一些有趣的事情,用户验证就是其中一个很有意思的功能。具体用法:...
  • Kong 基础认证插件 ( Basic auth ) Kong 网关有许许多多的插件,接下来我们首先来看下 AUTHENTICATION模块下的基础认证 ( Basic Auth )插件。下文将会详细讲解其实现 什么是 Basic Auth? 基本认证是基于 ...
  • Basic Auth一、简介在HTTP中,基本认证(Basic access authentication)是一种用来允许网页浏览器或其他客户端程序在请求时提供用户名和口令形式的身份凭证的一种登录验证方式。优点基本认证的一个优点是基本上所有...
  • SpringBoot - 集成Auth0 JWT

    千次阅读 2021-08-19 00:39:08
    JWT的类库 Java 中的 JWT 有很多类库,关于其优缺点可以在官网查看:https://jwt.io/,这里我们介绍Auth0的JWT的集成使用方式 Auth0 实现的 com.auth0 / java-jwt / 3.3.0 Brian Campbell 实现的 org.bitbucket.b_c...
  • 我想使用auth_request模块.我想通过传递密钥来检查请求是否有效.所以像:http://domain.com/hls/stream.m3u8?key=xxxxxxx我在Nginx.conf中具有以下设置:location /hls {alias /tmp/hls;auth_request /hls/auth;}...
  • I am trying to run this command in laravel 5.2 but it's not working.php artisan make:authand prompts with these statements.[InvalidArgumentException]Command "make:auth" is not definedDid you mean one ...
  • 当使用拦截器实现功能后,领导终于祭出大招了:我们已经有一个 Auth 参数了,appkey 可以从 Auth 参数里取到,可以把在不在白名单作为 Auth 的一种方式,为什么不在 Auth 时校验?emmm... 吐血中。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 548,321
精华内容 219,328
关键字:

auth