项目班 03 用户登录与注册

项目班 03 用户登录与注册

  需要导入 redis和 packet

pip install redis

pip install packet

  app.py 用于保存用户登录信息的cookie设置

import os

import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define,options

from handlers import main,auth


define('port',default='8000',help='Listening port',type=int)

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            ('/',main.IndexHandler),
            ('/explore', main.ExploreHandler),
            ('/post/(?P<post_id>[0-9]+)', main.PostHandler),
            ('/upload', main.UploadHandler),
            ('/login', auth.LoginHandler),
            ('/logout', auth.LogoutHandler),
            ('/signup', auth.SignupHandler),
        ]
        settings = dict(
            debug = True,
            template_path = 'templates',
            static_path = os.path.join(os.path.dirname(__file__),'static'),
            login_url = '/login',#要让必须登录之后才能访问首页
            cookie_secret = '95815451dasdwa1',#加密cookie的字符串
            pycket = { #固定写法packet,用于保存用户登录信息
                'engine':'redis',
                'storage':{
                    'host':'localhost',
                    'port':6379,
                    # 'password':''
                    'db_sessions':5,
                    'db_notifications':11,
                    'max_connections':2 ** 30
                },
                'cookie':{
                    'expires_days':30,
                },
            }
        )

        super(Application,self).__init__(handlers,**settings)

application = Application()

if __name__ == '__main__':
    tornado.options.parse_command_line()
    application.listen(options.port)
    print("Server start on port {}".format(str(options.port)))
    tornado.ioloop.IOLoop.current().start()

  templates/base.html 模板页面更新,添加登出按钮,更改样式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Tornado Title {% end %}</title>
</head>
<body>
<div style="width: 200px;height: 100px;display: block;">
    <a href="/logout">登出</a>
</div>
<div style="width: auto; text-align:center">
        {% block content %} base content {% end %}
    </div>
</body>
</html>

  handlers/main.py 主函数更新

import tornado.web
import os
from pycket.session import SessionMixin
from utils import photo

class AuthBaseHandler(tornado.web.RequestHandler,SessionMixin):
    def get_current_user(self):
        return self.session.get('tudo_user_info') #session是一种会话状态,跟数据库的session可能不一样

class IndexHandler(AuthBaseHandler):
    """
    Home page for user,photo feeds
    """
    @tornado.web.authenticated #要让首页必须登录之后才可以访问,用这个装饰器就可以,但是要在app.py里面设置login_url
    def get(self,*arg,**kwargs):
        images_path = os.path.join(self.settings.get('static_path'),'uploads')
        images = photo.get_images(images_path)
        self.render('index.html',images = images)

  utils/account.py 专门放与用户相关的函数,比如判断用户密码是否匹配等等

'''
用户相关的函数
'''

import hashlib#系统自带的加密库 hash加密


USER_DATA = {#用于判断用户密码是否匹配
    'name':'tudo',
    'password':hashlib.md5('123qwe'.encode('utf8')).hexdigest(),#给密码加密,用hashlib来算法加密,utf8不加的话就是默认utf8
}

def authenticate(username,password):#用户密码匹配判断函数
    if username and password:
        hash_pw = hashlib.md5(password.encode()).hexdigest()#给输入的密码进行算法加密
        if username == USER_DATA['name'] and hash_pw == USER_DATA['password']:#如果用户密码与数据库里面的用户密码匹配
            return  True
    return False

  handlers/auth.py 用户登录认证

'''
此文件是专门针对认证的
'''

import tornado.web
from utils.account import authenticate
from .main import AuthBaseHandler


class LoginHandler(AuthBaseHandler): #登录的路由

    def get(self, *args, **kwargs):
        if self.current_user:#如果用户已经登录
            self.redirect('/')#那么就直接跳转到主页
        self.render('login.html')

    def post(self, *args, **kwargs):
        username = self.get_argument('username',None) #获取用户
        password = self.get_argument('password',None) #获取密码

        passed = authenticate(username,password)#调用用户密码校验函数

        if passed:
            self.session.set('tudo_user_info',username)#将前面设置的cookie设置为username,保存用户登录信息
            self.redirect('/') #跳转主页路由

        else:
            self.write({'msg':'login fail'})#不通过,有问题

class LogoutHandler(AuthBaseHandler):#登出的路由

    def get(self):
        self.session.set('tudo_user_info','')#将用户的cookie清除
        self.redirect('/login')#返回登录路由

class SignupHandler(AuthBaseHandler):#注册的路由

    def get(self,*args,**kwargs):
        self.render('signup.html')

    def post(self):
        username = self.get_argument('username','')
        email = self.get_argument('email','')
        password1 = self.get_argument('password1','')
        password2 = self.get_argument('password2','')

        if username and password1 and password2:
            if password1 != password2:
                self.write({'mfg':'两次输入的密码不同'})
            else:
                pass

  templates/login.html 登录页面

{% extends 'base.html' %}

{% block title %} login page {% end %}

{% block content %}
<div class="">
    <div class="">
        <form action="/login?next={{ '/' }}" method="post" enctype="multipart/form-data">#依次是发送表单数据的路由,发送表单数据的函数,和固定写法
            <div class="form-group">
                Username
                <input autofocus="" class="form-control" id="id_username" maxlength="254" name="username" type="text" required="">
            </div>
            <div class="form-group">
                Password
                <input class="from-control" id="id_password" name="password" type="password" required="">
            </div>
            <button class="">Login</button>
            <div>
                还没有账号,需要 <a href="/signup">注册</a>一个
            </div>
        </form>
    </div>
</div>

{% end %}

  templates/signup.html 注册页面

{% extends 'base.html' %}

{% block title %} tagram page {% end %}

{% block content %}
<div class="">

    <form action="/signup/" method="post" enctype="multipart/form-data">
            <div class="form-group">
                Username
                <input autofocus="" class="form-control" id="id_username" maxlength="150" name="username" type="text" required="">
            </div>
            <div class="form-group">
                Email
                <input class="form-control" id="id_email" name="email" type="email" required="">
            </div>
            <div class="form-group">
                Password
                <input class="from-control" id="id_password1" name="password1" type="password" required="">
            </div>
            <div class="form-group">
                Password confirmation
                <input class="from-control" id="id_password2" name="password2" type="password" required="">
            </div>
            <button class="btn btn-default">注册</button>
            <div class="text-canter help-text">
                已有账号请 <a href="/login">登录</a>
            </div>
    </form>
</div>

{% end %}

猜你喜欢

转载自www.cnblogs.com/xuchengcheng1215/p/9150108.html