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表了。

 

posted @ 2019-08-11 15:15  邹邹很busy。  阅读(227)  评论(0编辑  收藏  举报