zoukankan      html  css  js  c++  java
  • django使用auth模块进行身份认证

    https://docs.djangoproject.com/zh-hans/2.0/topics/auth/default/#authentication-in-web-requests

    django认证模型系统是django自带,默认配置文件在settings.py文件当中。这个项目在INSTALLED_APPS setting里面由两个部分组成,分别是:

    1. 'django.contrib.auth' 包含了认证框架的核心模块, 是默认的模型。
    2. 'django.contrib.contenttypes' 是django的内容类型系统, 这个会允许你连接你创建的模型。

    这是你的中间件配置:

    1. SessionMiddleware manages sessions across requests.
    2. AuthenticationMiddleware associates users with requests using sessions.

    一、创建超级用户

    $ python manage.py createsuperuser --username=joe --email=joe@example.com

    更改密码

    from django.contrib.auth.models import User
    u = User.objects.get(username='john')
    u.set_password('new password')
    u.save()

    # 这里的User是django默认创建的用户表,如果用到自己定义的表,这里需要更改,更改后的表含有User表所有的方法。

    检查密码

    auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。
    密码正确返回True,否则返回False。
    用法:
    ok = user_obj.check_password('密码')
    或者
    ok = request.user.check_password(raw_password='原密码')

    一个简单的修改密码功能的事例:

    @login_required
    def set_password(request):
        user = request.user
        err_msg = ''
        if request.method == 'POST':
            old_password = request.POST.get('old_password', '')
            new_password = request.POST.get('new_password', '')
            repeat_password = request.POST.get('repeat_password', '')
            # 检查旧密码是否正确
            if user.check_password(old_password):
                if not new_password:
                    err_msg = '新密码不能为空'
                elif new_password != repeat_password:
                    err_msg = '两次密码不一致'
                else:
                    user.set_password(new_password)
                    user.save()
                    return redirect("/login/")
            else:
                err_msg = '原密码输入错误'
        content = {
            'err_msg': err_msg,
        }
        return render(request, 'set_password.html', content)
    
    修改密码示例
    View Code

    验证用户

    from django.contrib.auth import authenticate
    user = authenticate(username='john', password='secret')
    if user is not None:
        # 验证通过
        # A backend authenticated the credentials
    else:
        # 验证失败
        # No backend authenticated the credentials

    request is an optional HttpRequest which is passed on the authenticate() method of the authentication backends.

     Changed in Django 1.11:

    The optional request argument was added.

    权限和认证

    User objects have two many-to-many fields: groups and user_permissionsUser objects can access their related objects in the same way as any other Django model:

    myuser.groups.set([group_list])
    myuser.groups.add(group, group, ...)
    myuser.groups.remove(group, group, ...)
    myuser.groups.clear()
    myuser.user_permissions.set([permission_list])
    myuser.user_permissions.add(permission, permission, ...)
    myuser.user_permissions.remove(permission, permission, ...)
    myuser.user_permissions.clear()
    
    
    from django.contrib.auth.models import User
    
    u = User.objects.get(username='john')
    u.groups.add()
    或
    u = User.objects.get(username='john')
    u.user_permissions.add()

    默认权限

    假设我创建了一个app名称叫做foo,model名称叫做Bar,测试你所拥有的基本权限方法如下:

    add: user.has_perm('foo.add_bar')
    change: user.has_perm('foo.change_bar')
    delete: user.has_perm('foo.delete_bar')

    权限缓存

    from django.contrib.auth.models import Permission, User
    from django.contrib.contenttypes.models import ContentType
    from django.shortcuts import get_object_or_404
    
    from myapp.models import BlogPost
    
    def user_gains_perms(request, user_id):
        user = get_object_or_404(User, pk=user_id)
        # any permission check will cache the current set of permissions
        user.has_perm('myapp.change_blogpost')
    
        content_type = ContentType.objects.get_for_model(BlogPost)
        permission = Permission.objects.get(
            codename='change_blogpost',
            content_type=content_type,
        )
        user.user_permissions.add(permission)
    
        # Checking the cached permission set
        user.has_perm('myapp.change_blogpost')  # False
    
        # Request new instance of User
        # Be aware that user.refresh_from_db() won't clear the cache.
        user = get_object_or_404(User, pk=user_id)
    
        # Permission cache is repopulated from the database
        user.has_perm('myapp.change_blogpost')  # True
    
        ...

    Web 请求的认证

    django使用session中间件来验证request objects,如果用户验证没有通过,这个实例会被设置成AnonymousUser

    if request.user.is_authenticated: # Do something for authenticated users. ... else: # Do something for anonymous users. ...

    如何使用authenticate()login():

    from django.contrib.auth import authenticate, login
    
    def my_view(request):
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            # Redirect to a success page.
            ...
        else:
            # Return an 'invalid login' error message.
            ...

    用户如何登出

    from django.contrib.auth import logout
    
    def logout_view(request):
        logout(request)
        # Redirect to a success page.

    Limiting access to logged-in users

    from django.conf import settings
    from django.shortcuts import redirect
    
    def my_view(request):
        if not request.user.is_authenticated:
            return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
        # ...

    或者返回一个错误页面

    from django.shortcuts import render
    
    def my_view(request):
        if not request.user.is_authenticated:
            return render(request, 'myapp/login_error.html')
        # ...

    login_required 装饰器

    使用方法如下

    from django.contrib.auth.decorators import login_required
    
    @login_required
    def my_view(request):
        ...

    登陆成功后默认会跳转到/accounts/login/目录,如果需要使用自定义目录,需要添加在settings.py文件LOGIN_URL 参数。

    测试登陆用户,验证用户是否存在email字段

    from django.shortcuts import redirect
    
    def my_view(request):
        if not request.user.email.endswith('@example.com'):
            return redirect('/login/?next=%s' % request.path)
        # ...

    user_passes_test(test_funclogin_url=Noneredirect_field_name='next')[source]

    As a shortcut, you can use the convenient user_passes_test decorator which performs a redirect when the callable returns False:

    from django.contrib.auth.decorators import user_passes_test
    
    def email_check(user):
        return user.email.endswith('@example.com')
    
    @user_passes_test(email_check)
    def my_view(request):

    permission_required 装饰器

    permission_required(permlogin_url=Noneraise_exception=False)[source]

    from django.contrib.auth.decorators import permission_required
    
    @permission_required('polls.can_vote')
    def my_view(request):
        ...

    就好像has_perm方法一样,permission_requierd使用方法为<app label>.<permission codename>

    注意permission_required()仍然需要login_url字段。作为login_required的装饰,login_url默认设置的为settings.LOGIN_URL,也就是settings.py文件当中的LOGIN_URL参数。

    如果raise_exception字段抛出,这个装饰会抛出PermissionDenied,403 Forbidden,而不是跳转的login页面。如果你想要在异常抛出前再给你的用户登陆,你可以加上login_required()

    from django.contrib.auth.decorators import login_required, permission_required
    
    @login_required
    @permission_required('polls.can_vote', raise_exception=True)
    def my_view(request):

    Session invalidation on password change

    如果用户认证的model从 AbstractBaseUser 或者从get_session_auth_hash()方法实现,通过这些,认证缓存会通过hash方法实现,在AbstractBaseUser例子中,如果你想要更改密码并且不退出登陆,使用update_session_auth_hash()方法。

    from django.contrib.auth import update_session_auth_hash
    
    def password_change(request):
        if request.method == 'POST':
            form = PasswordChangeForm(user=request.user, data=request.POST)
            if form.is_valid():
                form.save()
                update_session_auth_hash(request, form.user)
        else:
            ...

     如何扩展自带的auth_user表

    1. 新建一个表, 一对一关联上面的auth_user表

    2. 继承的方式

    from django.contrib.auth.models import AbstractUser
            
    class UserInfo(AbstractUser):
        phone = models.CharField(max_length=11)
        addr = models.CharField(max_length=128)
        相当于对默认的auth_user表做了扩展, 并且代替auth_user

    注意:
    在settings.py中一定要加
    AUTH_USER_MODEL = 'app名.类名'

    https://docs.djangoproject.com/zh-hans/2.0/topics/auth/default/#authentication-in-web-requests

  • 相关阅读:
    RabbitMQ 安装
    redis windows安装
    Python Scrapy 爬取煎蛋网妹子图实例(二)
    Python Scrapy 爬取煎蛋网妹子图实例(一)
    Python pymysql 增删改查封装
    Python Scrapy 爬虫框架实例(一)
    Mac Anaconda 简单介绍 -- 环境管理
    python Scrapy 常见问题记录
    Hive json字符串解析
    大数据
  • 原文地址:https://www.cnblogs.com/ttyypjt/p/10545782.html
Copyright © 2011-2022 走看看