zoukankan      html  css  js  c++  java
  • django -- auth模块

    前戏

    我们在开发项目的时候,难免要遇到用户权限的问题,例如这个用户是不是可以访问这个页面,是不是可以登录,账号是不是已经过期了等等的原因,django给我们提供了auth模块,能很方便的解决我们的这些问题。

    django给我们提供了一个后台管理系统,我们先来创建一个超级用户,在项目跟目录下执行下面命令

    python manage.py createsuperuser

    执行成功之后,我们就在默认的auth_user表里创建了一个用户

    我们可以登录到后台看看

    User下的数据就是我们数据表auth_user里的数据,方便我们进行数据的更改。

    authenticate

    给我们提供了用户认证功能,就是验证我们的用户名和密码是不是正确的。一般需要username和password两个参数,如果认证成功,则返回一个User对象,如果认证失败,则返回None

    authenticate()会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。

    我们可以写一个登录函数,来判断我们输入的用户名和密码是不是正确的,我们上面已经注册了一个账号和密码

     1 from django.contrib import auth
     2 
     3 
     4 def login(request):
     5     if request.method == 'POST':
     6         username = request.POST.get('username')
     7         pwd = request.POST.get('pwd')
     8         obj = auth.authenticate(request, username=username, password=pwd)
     9         print(obj)
    10         if obj:
    11             return redirect('/index/')
    12 
    13     return render(request, 'login.html')

    代码解释:

    第八行我们通过authenticate进行判断用户名和密码是不是正确,里面有三个参数,第一个是request,第二个是用户名,前面的username是数据库里的字段名,后面的是用户输入的值,第三个是密码。如果验证通过,则obj是一个User对象,如果验证失败,则obj为None

     login()

    该函数实现一个用户登录的功能,它会在后端为该用户生成一个seeeion数据,存在django_session表里。

    该函数接收一个HttpRequest对象,以及一个经过认证的User对象。

    1 def login(request):
    2     if request.method == 'POST':
    3         username = request.POST.get('username')
    4         pwd = request.POST.get('pwd')
    5         obj = auth.authenticate(request, username=username, password=pwd)
    6         if obj:
    7             auth.login(request, obj)  # obj是上面认证返回的对象
    8             return redirect('/index/')
    9     return render(request, 'login.html')

    这样,当我们执行到第七行的时候,会自动为我们生成session。

    logout()

    当调用该函数时,当前请求的session信息会全部清除,该用户即使没有登录,使用该方法也不会报错,接收一个HttpRequest对象,无返回值。

    我们在上面登录成功之后会进入到index页面,在index视图里写个注销的功能

    def index(request):
        auth.logout(request)  # 清除用户的session数据
        return redirect('/login/')

    login_requierd()

    有些页面我们需要用户登录成功之后才能访问,在之前我们通过给设置cookie,获取cookie的方法来判断,django给我们提供了这样的功能,使用装饰器login_requierd()就能实现,首先需要导入

    from django.contrib.auth.decorators import login_required

    我们给index视图加上装饰器,在没登录的状态下访问

    from django.contrib.auth.decorators import login_required
    
    @login_required  # 使用装饰器添加登录校验
    def index(request):
    
        return HttpResponse('index')

    django报错,提示我们

    Not Found: /accounts/login/

    这是因为如果没有登录,django会跳转到 /accounts/login/ 这个路由,因为这个我们没有定义,所以会报错,我们把login改成 /accounts/login/ 就会跳转到登录页面了,如果不想改,就想用login。可以在settings.py里加上下面的代码

    LOGIN_URL = '/login/'  # 这里配置成你项目登录页面的路由

    这样我们就能使用我们自定义的路由了,访问index页面,如果没有登录,跳转的路由为

    http://127.0.0.1:8000/login/?next=/index/

    在上面登录的视图函数里,我们登录成功后会访问固定的页面index,但是我们可能是从home页面访问的,登录之后还想回到home页面,这时我们就可以修改login视图函数了

    def login(request):
        if request.method == 'POST':
            username = request.POST.get('username')
            pwd = request.POST.get('pwd')
            obj = auth.authenticate(request, username=username, password=pwd)
            if obj:
                auth.login(request, obj)  # obj是上面认证返回的对象
                next_page = request.GET.get('next')  # django给我们提供的参数是next,所以我们通过next拿到对应的值,在通过重定向跳转到对应的页面
                if next_page:
                    return redirect(next_page)
                return HttpResponse('ok')
        return render(request, 'login.html')

     is_authenticated()

    用来判断当前请求是否通过了认证,通过了返回True,没通过返回False

    from django.contrib.auth.decorators import login_required
    
    
    def login(request):
        if request.method == 'POST':
            username = request.POST.get('username')
            pwd = request.POST.get('pwd')
            obj = auth.authenticate(request, username=username, password=pwd)
            if obj:
                auth.login(request, obj)  # obj是上面认证返回的对象
                next_page = request.GET.get('next')  # django给我们提供的参数是next
                if next_page:
                    return redirect(next_page)
                return HttpResponse('ok')
        return render(request, 'login.html')
    
    
    @login_required  # 使用装饰器添加登录校验
    def index(request):
        print(request.user, type(request.user))  # 当前的用户对象
        print(request.user.is_authenticated())  # 判断当前用户是否登录
    
        return HttpResponse('index')

    create_user()

    创建新用户的方法,必须要提供username,password参数。也可以指定其他参数

    要导入对应的模块

    from django.contrib.auth.models import User
    from django.contrib.auth.models import User
    
    
    def register(request):
        if request.method == 'POST':
            user = request.POST.get('username')
            pwd = request.POST.get('password')
            User.objects.create_user(username=user, password=pwd)  # 创建一个用户
            return redirect('/login/')
    
        return render(request, 'register.html')

    指定其他参数,数据库里要有这个字段

    User.objects.create_user(is_staff=1,username=user, password=pwd)

    create_superuser()

    创建一个超级用户,可以登录到后台

    语法和上面的一样

    from django.contrib.auth.models import User
    
    User.objects.create_superuser(email='',username=user, password=pwd)  # 有三个参数,email在这里写死了

    check_password()

    auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。

    密码正确返回True,否则返回False。

    user.check_password('密码')

    set_password()

    auth 提供的一个修改密码的方法,接收 要设置的新密码作为参数。

    注意:要使用save()方法才能保存到数据库里面

    from django.contrib.auth.models import User
    
    user.set_password(password='新密码')
    user.save()

    自定义auth_user表

    django虽然给我们提供了user表来存储用户的注册账号等信息,但不能满足我们实际项目的需求,比如我们还需要用户填地址,手机号等等信息。

    我们可以通过继承内置的 AbstractUser 类,来定义一个自己的Model类。

    from django.contrib.auth.models import AbstractUser
    
    
    class UserInfo(AbstractUser):
        addr = models.CharField(max_length=32)
        phone = models.CharField(max_length=11)

    注意:

    按上面的方式扩展了内置的auth_user表之后,一定要在settings.py中告诉Django,我现在使用我新定义的UserInfo表来做用户认证。写法如下:

    # 引用Django自带的User表,继承使用时需要设置
    AUTH_USER_MODEL = "app名.UserInfo"

    一旦我们指定了新的认证系统所使用的表,我们就需要重新在数据库中创建该表,而不能继续使用原来默认的auth_user表了。

  • 相关阅读:
    机器学习(深度学习)
    机器学习(六)
    机器学习一-三
    Leetcode 90. 子集 II dfs
    Leetcode 83. 删除排序链表中的重复元素 链表操作
    《算法竞赛进阶指南》 第二章 Acwing 139. 回文子串的最大长度
    LeetCode 80. 删除有序数组中的重复项 II 双指针
    LeetCode 86 分割链表
    《算法竞赛进阶指南》 第二章 Acwing 138. 兔子与兔子 哈希
    《算法竞赛进阶指南》 第二章 Acwing 137. 雪花雪花雪花 哈希
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11273613.html
Copyright © 2011-2022 走看看