zoukankan      html  css  js  c++  java
  • 项目 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=" 200px;height: 100px;display: block;">
        <a href="/logout">登出</a>
    </div>
    <div style=" 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 %}
  • 相关阅读:
    BZOJ5057 : 区间k小值5
    Urozero Autumn 2016. UKIEPC 2016
    BZOJ2808 : 那些年我们画格子
    BZOJ4970 : [ioi2004]empodia 障碍段
    XVII Open Cup named after E.V. Pankratiev. XXI Ural Championship
    BZOJ4316 : 小C的独立集
    网络流(3)——找到最小st-剪切
    网络流(2)——用Ford-Fullkerson算法寻找最大流
    网络流(1)——网络、流网络和网络流
    退而求其次(4)——椭圆中的最大矩形
  • 原文地址:https://www.cnblogs.com/xuchengcheng1215/p/9150108.html
Copyright © 2011-2022 走看看