Django Auth

Django Admin

————————个人的一些doc摘录

Composition

  • accounts
  • permission
  • group
  • cookie-based user sessions

Auth system handles:

  • Authtication
    • verify who the user is
  • Authorization
    • determine what an authenticated user is allowed to manipulate

COMPOSITION

  • Users
  • Permission: binary flag to dertermine wether a user is able to perform a task
  • Groups: apply label and permission to some uses in common
  • Password hashing system
  • Form and view system
  • Pluggbale backend system

USER

User Objects
  • username
  • password
  • email
  • first_name
  • last_name
Create Users
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('tree', 'tree@inad.com', 'password')

# At this point, user is a User object that has already been saved
# to the database. You can continue to change its attributes
# if you want to change other fields.
>>> user.last_name = 'Lennon'
>>> user.save()
Create Superusers
python manage.py createsuperuser --username=Tree --emial=shuwei@inad.com

The admin site is designed to utilze by superuser.

Change Password

In user model, django does not store raw password but hash. So there are two ways to manipulate:


  • python manage.py changepassword 'username' <new password>

You will be asked to enter twice, the new password established if matched. If a username is not provided, django will attempt to change password of the current user.

  • *
from django.contrib.auth import User
u = User.objects.get(username='Tree')
u.set_password('123')
u.save()

Changing a user’s password will log out all their sessions if the SessionAuthenticationMiddleware is enabled.

Authenticaing Users
from django.contrib.auth import authenticate
user = authenticate(username='tree', password='secret')
if user is not None:
    # the password verified for the user
    if user.is_active:
        print("User is valid, active and authenticated")
    else:
        print("The password is valid, but the account has been disabled!")
else:
    # the authentication system was unable to verify the username and password
    print("The username and password were incorrect.")

Django tries authenticating across all of its authentication backends. If the first authentication method fails, he tries the second one, and so on, until all backends have been attempted.

Permission & Authorization

User object have two many-to-many fields: groups and user_permissions

request.user attribute is used in every request to represent the current.

if request.user.is_authenticated():
    # Do something for authenticated users.
else:
    # Do something for anonymous users.
How to log a user in

login() function takes a HttprRequest and a User object.

from django.contrib.auth import authenticate, login

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

When you’re manually logging a user in, you must call authenticate() before you call login().

How to log a user out
from django.contrib.auth import logout

def logout_view(request):
    logout(request)
    # Redirect to a success page.

All session data will be cleaned out immediately.

Userful Decorators

@login_required
  • If the user isn’t logged in, redirect to LOGIN_URL, passing the current absolute path in the query string. Example: /accounts/login/?next=/reviews/3/.
  • If the user is logged in, execute the view normally. The view code is free to assume the user is logged in.

By default, the path that the user should be redirected to upon successful authentication is stored in a query string parameter called “next”. If you would prefer to use a different name for this parameter, login_required() takes an optional redirect_field_name parameter: @login_required(login_url='/accounts/login/')

The login_required decorator does NOT check the is_active flag on a user.

@user_pass_test

To limit access based on certain permissions or some other test:

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):
    ...

user_passes_test() optional arguments:login_urlLets you specify the URL that users who don’t pass the test will be redirected to. It may be a login page and defaults to LOGIN_URL if you don’t specify one.

@permission_required

It’s a relatively common task to check whether a user has a particular permission and takes a . like positional argument.

from django.contrib.auth.decorators import permission_required

@permission_required('reviews.can_vote', login_url='/loginpage/')
def my_view(request):
    ...

Extending user model

  • Scene 1

from django.conf import settings
from django.db import models

class Myclass(models.Model)
owner = models.onetoonefield(settings.AUTH_USER_MODEL)

  • Scene 2
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User

from app.models import Employee

# Define an inline admin descriptor for Employee model
class EmployeeInline(admin.StackedInline):
    model = Employee

# Define a new User admin
class UserAdmin(UserAdmin):
    inlines = (EmployeeInline, )

# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)

In this case, when a User object is created, use ‘django.db.models.signals.post_save’ to update the related model at the same time.

Custom User Model

from django.contrib.auth.models import AbstractUser
from django.db import models

class MyUser(AbstractUser):
    name = models.CharField()

in settings:
AUTH_USER_MODEL = 'app.MyUser' 

Changing AUTH_USER_MODEL has a big effect on your database structure. It changes the tables that are available, and it will affect the construction of foreign keys and many-to-many relationships. If you intend to set AUTH_USER_MODEL, you should set it before creating any migrations or running manage.py migrate for the first time.

Custom authentication backend

from django.conf import settings
from django.contrib.auth.models import User, check_password

class SettingsBackend(object):
    """
    Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.

    Use the login name, and a hash of the password. For example:

    ADMIN_LOGIN = 'admin'
    ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
    """

    def authenticate(self, username=None, password=None):
        login_valid = (settings.ADMIN_LOGIN == username)
        pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
        if login_valid and pwd_valid:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                # Create a new user. Note that we can set password
                # to anything, because it won't be checked; the password
                # from settings.py will.
                user = User(username=username, password='get from settings.py')
                user.is_staff = True
                user.is_superuser = True
                user.save()
            return user
        return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Then we can handle custom authorization in this backend:

class SettingsBackend(object):
    ...
    def has_perm(self, user_obj, perm, obj=None):
        if user_obj.username == settings.ADMIN_LOGIN:
            return True
        else:
            return False            

Custom permission

To create custom permissions for a given model object, use the permissions model Meta attribute.

class Task(models.Model):
    ...
    class Meta:
        permissions = (
            ("view_task", "Can see available tasks"),
            ("change_task_status", "Can change the status of tasks"),
            ("close_task", "Can remove a task by setting its status as closed"),
        )

The only thing this does is create those extra permissions when you run manage.py migrate.
The following checks if a user may view tasks:

user.has_perm('app.view_task')

TIPS

It is not worth to heavily customize the Django admin. It is desifned for administrators not end users.

You can give your models custom permissions that can be checked through Django’s authorization system.

You can extend the default User model, or substitute a completely customized model.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值