Django——用户创建登录注销验证

先配置数据库settings中

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_user',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': 'localhost',
        'PORT': 3306
    }
}

app urls

# coding:utf-8

from django.urls import path
from .views import Regist

urlpatterns = [
    path('regist', Regist.as_view(), name='regist')
]

views

# coding:utf-8

from django.shortcuts import render
from django.views.generic import View

class Regist(View):
    TEMPLATE = 'regist.html'

    def get(self, request):

        return render(request, self.TEMPLATE)

templates中的regist(记得注册templates)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
    <form>
        <input type="text" placeholder="请输入用户名">
        <input type="password" placeholder="请输入密码">
        <input type="password" placeholder="确认密码">
        <input type="submit" value="提交">
        <input type="reset" value="重置">

    </form>

</body>
</html>

启动后
在这里插入图片描述
display:
block:每个input占据一行
inline:input默认是inline
inline-block:把一个行级元素内容有了一个块级元素

下图为block效果
在这里插入图片描述
margin-left: 50% 距离左边有50%的间距。
float:right 到最右边(不过层级会改变)
margin-top: 50px:距离最上面50像素。

csrf是一种保护机制,是为了防止一种跨站的恶意攻击,才出现的一种加密的访问。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
    <style>
        #edit-area{
            width: 25%;
            margin: 0 auto;
            margin-top: 50px;

        }
        input{
            display: block;
            width: 100%;
        }
        #submit, #reset{
            width: 40px;
            display: inline-block;
        }
        #reset{
            float: right;
        }


    </style>


</head>
<body>
    <form id="edit-area" action="{% url 'regist' %}" method="post">
        {% csrf_token %}
        <input type="text" placeholder="请输入用户名">
        <input type="password" placeholder="请输入密码">
        <input type="password" placeholder="确认密码">
        <input id="submit" type="submit" value="提交">
        <input id="reset" type="reset" value="重置">

    </form>

</body>
</html>

把前端数据和后端关联:
加上name

<input name="username" type="text" placeholder="请输入用户名">
        <input name="password" type="password" placeholder="请输入密码">
        <input name="check_password" type="password" placeholder="确认密码">
        <input id="submit" type="submit" value="提交">
        <input id="reset" type="reset" value="重置">

然后后端拿到表单post的内容。views中加上post

    def post(self, request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        check_password = request.POST.get('check_password')

        print(username, password, check_password)

        return redirect('/regist')

在这里插入图片描述
收到了,

注册

接下来对数据进行一个注册。views中

class Regist(View):
    TEMPLATE = 'regist.html'

    def get(self, request):
        error = request.GET.get('error', '')  # 拿到post中 密码输入不同后error的值 然后在前端显示出来

        return render(request, self.TEMPLATE, {'error': error})

    def post(self, request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        check_password = request.POST.get('check_password')

        if password != check_password:
            return redirect('/regist?error=密码不同')

        print(username, password, check_password)

        return redirect('/regist')

在这里插入图片描述

# coding:utf-8

from django.contrib.auth.models import User
from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from django.contrib.auth.hashers import make_password  # 加密工具

class Regist(View):
    TEMPLATE = 'regist.html'

    def get(self, request):
        error = request.GET.get('error', '')  # 拿到post中 密码输入不同后error的值 然后在前端显示出来

        return render(request, self.TEMPLATE, {'error': error})

    def post(self, request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        check_password = request.POST.get('check_password')

        if password != check_password:
            return redirect('/regist?error=密码不同')

        # 验证一下username是否已经注册了
        exists = User.objects.filter(username=username).exists()
        if exists:  # 如果是1 就是已经注册了
            return redirect('/regist?error=该用户名已存在')


        hash_password = make_password(password)  # 如果密码前后一致,就哈希加密一下

        user = User.objects.create_user(username=username, password=hash_password)
        user.save()

        return redirect(reverse('login'))

class Login(View):
    TEMPLATE = 'login.html'

    def get(self, request):

        return render(request, self.TEMPLATE)

注册成功了,会跳转到login页面

先更新一下数据库,然后在页面注册一下:
在这里插入图片描述
然后在数据库中能看到注册的用户,密码被加密了,不是staff也不是超级管理员。
现在注册就完成了,接下来是登录。

登录

login页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
    <style>
        form {
            width: 20%;
            margin: 0 auto;
            margin-top: 100px;
            padding: 2%;
            border: 1px solid #cccccc;
            border-radius: 8px;
        }
    </style>

</head>
<body>
    <form>
        <input type="text" name="username" placeholder="用户名" required>
        <input type="password" name="password" placeholder="密码" required>
        <input type="submit" value="登录">

    </form>
</body>

#cccccc一种灰色
padding 简写属性在一个声明中设置所有内边距属性。

说明
这个简写属性设置元素所有内边距的宽度,或者设置各边上内边距的宽度。行内非替换元素上设置的内边距不会影响行高计算;因此,如果一个元素既有内边距又有背景,从视觉上看可能会延伸到其他行,有可能还会与其他内容重叠。元素的背景会延伸穿过内边距。不允许指定负边距值。
例子 1
padding:10px 5px 15px 20px;
上内边距是 10px
右内边距是 5px
下内边距是 15px
左内边距是 20px
border-radius:添加圆角
在这里插入图片描述
完整views

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
    <style>
        form {
            width: 20%;
            margin: 0 auto;
            margin-top: 100px;
            padding: 2%;
            border: 1px solid #cccccc;
            border-radius: 8px;
        }
        input {
            display: block;
            width: 100%;
        }

        #submit{
            width: 40px;
        }

    </style>

</head>
<body>
    <form action="{% url 'login' %}" method="post">
        {% csrf_token %}
        <input type="text" name="username" placeholder="用户名" required>
        <input type="password" name="password" placeholder="密码" required>
        <input id="submit" type="submit" value="登录">

    </form>
</body>

然后后端要对post接收一下:

from django.contrib.auth import login, logout, authenticate  # 登录验证 和登出 验证

class Login(View):
    TEMPLATE = 'login.html'

    def get(self, request):

        return render(request, self.TEMPLATE)

    def post(self, request):

        username = request.POST.get('username')
        password = request.POST.get('password')

        # 拿到username 和 password之后要先对其进行验证
        user = authenticate(username=username, password=password)

        if user:  # 如果用户存在
            print('login success! ', user)
        else:
            print('login fail ~ ', user)

        return redirect(reverse('login'))  # 这里的login前面不要加 /

先检验一下效果:
错误时:
在这里插入图片描述
这里尝试了一下正确输入,结果依旧是fail。
推断可能是注册部分:

# hash_password = make_password(password)  # 如果密码前后一致,就哈希加密一下
user = User.objects.create_user(username=username, password=password)

这里用的是create_user,会自动将我们的password加入然后存入,就不需要手动再hash了。
如果是用create的话,就需要手动hash。
于是我们把之前的user删掉再重新注册一下:
在这里插入图片描述
看到上面确实是自动加密的了。

在这里插入图片描述
然后我们这里也显示success

接下来写登入

    def get(self, request):

        error = request.GET.get('error')

        return render(request, self.TEMPLATE, {'error':error})

    def post(self, request):

        username = request.POST.get('username')
        password = request.POST.get('password')

        # 拿到username 和 password之后要先对其进行验证
        user = authenticate(username=username, password=password)

        if user:  # 如果用户存在
            login(request, user)  # 登录
        else:
            return redirect('/login?error=登录失败')  # 登录错误就传一个error,get里面获取error的值

        return redirect(reverse('login'))  # 这里的login前面不要加 /

在这里插入图片描述
在这里插入图片描述
区分用户名错误和密码错误

    def post(self, request):

        username = request.POST.get('username')
        password = request.POST.get('password')

        exists = User.objects.filter(username=username).exists()

        # 先验证用户名是否存在
        if not exists:  # 如果用户名不存在
            return redirect('/login?error=没有该用户')

        # 上面验证完用户名,接下来就验证password
        user = authenticate(username=username, password=password)

        if user:  # 如果password正确
            login(request, user)  # 登录
        else:
            return redirect('/login?error=密码错误')  # 登录错误就传一个error,get里面获取error的值

        return redirect(reverse('login'))  # 这里的login前面不要加 /

在这里插入图片描述
在这里插入图片描述

登出:

class LogoutUser(View):

    def get(self, request):

        logout(request)

        return redirect(reverse('login'))  # 退出登录就让他再回到登录页面

urls也配置一下:

urlpatterns = [
    path('regist', Regist.as_view(), name='regist'),
    path('login', Login.as_view(), name='login'),
    path('logout', LogoutUser.as_view(), name='logout')
]

接下来确认是否成功登录:

class Regist(View):
    TEMPLATE = 'regist.html'

    def get(self, request):
        if request.user.is_authenticated:
            return redirect(reverse('login'))

因为我们的login页面无法logout,所以我们再增加一个logout按钮。

<body>
    {% if not user.is_authenticated %}
    <form action="{% url 'login' %}" method="post">
        {% csrf_token %}
        <input type="text" name="username" placeholder="用户名" required>
        <input type="password" name="password" placeholder="密码" required>
        <input id="submit" type="submit" value="登录">

        {{error}}
    </form>
    {% else %}
    <a href="{% url 'logout' %}">退出登录</a>
    {% endif %}

</body>

然后我们现在再创建一个superuser
在这里插入图片描述
进入admin看一下
在这里插入图片描述
状态不同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
步骤: 1. 安装pyjwt ``` pip install pyjwt ``` 2. 在Django创建一个自定义的认证后端 ```python from django.contrib.auth.backends import BaseBackend from django.contrib.auth import get_user_model from jwt.exceptions import ExpiredSignatureError, InvalidTokenError from jwt import encode, decode User = get_user_model() class JWTAuthenticationBackend(BaseBackend): def authenticate(self, request, **kwargs): token = kwargs.get('token', None) if token: try: decoded = decode(token, 'secret', algorithms=['HS256']) user = User.objects.get(username=decoded['username']) return user except (ExpiredSignatureError, InvalidTokenError, User.DoesNotExist): return None return None def get_user(self, user_id): try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None ``` 3. 在settings.py文件中配置认证后端 ```python AUTHENTICATION_BACKENDS = [ 'path.to.JWTAuthenticationBackend', 'django.contrib.auth.backends.ModelBackend', ] ``` 4. 在视图函数中添加JWT认证 ```python import datetime import jwt def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') user = authenticate(username=username, password=password) if user is not None: login(request, user) token = jwt.encode({'username': user.username, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30)}, 'secret', algorithm='HS256') return JsonResponse({'token': token}) else: return JsonResponse({'error': 'Invalid credentials'}) ``` 5. 在需要认证的视图函数中添加装饰器 ```python from django.contrib.auth.decorators import login_required @login_required(login_url='/login/') def protected_view(request): return JsonResponse({'data': 'You are logged in'}) ``` 6. 在前端发送请求时带上JWT token ```javascript fetch('/protected_view/', { headers: { 'Authorization': 'Bearer ' + token } }) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值