使用Python编写编写一个简单的登录界面面遇到问题

用Python实现web端用户登录和注册功能的教程
&更新时间:日 10:24:10 & 作者:廖雪峰
这篇文章主要介绍了用Python实现web端用户登录和注册功能的教程,需要的朋友可以参考下
用户管理是绝大部分Web网站都需要解决的问题。用户管理涉及到用户注册和登录。
用户注册相对简单,我们可以先通过API把用户注册这个功能实现了:
_RE_MD5 = re.compile(r'^[0-9a-f]{32}$')
@post('/api/users')
def register_user():
i = ctx.request.input(name='', email='', password='')
name = i.name.strip()
email = i.email.strip().lower()
password = i.password
if not name:
raise APIValueError('name')
if not email or not _RE_EMAIL.match(email):
raise APIValueError('email')
if not password or not _RE_MD5.match(password):
raise APIValueError('password')
user = User.find_first('where email=?', email)
raise APIError('register:failed', 'email', 'Email is already in use.')
user = User(name=name, email=email, password=password, image='http://www.gravatar.com/avatar/%s?d=mm&s=120' % hashlib.md5(email).hexdigest())
user.insert()
return user
注意用户口令是客户端传递的经过MD5计算后的32位Hash字符串,所以服务器端并不知道用户的原始口令。
接下来可以创建一个注册页面,让用户填写注册表单,然后,提交数据到注册用户的API:
{% extends '__base__.html' %}
{% block title %}注册{% endblock %}
{% block beforehead %}
function check_form() {
$('#password').val(CryptoJS.MD5($('#password1').val()).toString());
{% endblock %}
{% block content %}
&div class="uk-width-2-3"&
&h1&欢迎注册!&/h1&
&form id="form-register" class="uk-form uk-form-stacked" onsubmit="return check_form()"&
&div class="uk-alert uk-alert-danger uk-hidden"&&/div&
&div class="uk-form-row"&
&label class="uk-form-label"&名字:&/label&
&div class="uk-form-controls"&
&input name="name" type="text" class="uk-width-1-1"&
&div class="uk-form-row"&
&label class="uk-form-label"&电子邮件:&/label&
&div class="uk-form-controls"&
&input name="email" type="text" class="uk-width-1-1"&
&div class="uk-form-row"&
&label class="uk-form-label"&输入口令:&/label&
&div class="uk-form-controls"&
&input id="password1" type="password" class="uk-width-1-1"&
&input id="password" name="password" type="hidden"&
&div class="uk-form-row"&
&label class="uk-form-label"&重复口令:&/label&
&div class="uk-form-controls"&
&input name="password2" type="password" maxlength="50" placeholder="重复口令" class="uk-width-1-1"&
&div class="uk-form-row"&
&button type="submit" class="uk-button uk-button-primary"&&i class="uk-icon-user"&&/i& 注册&/button&
{% endblock %}
这样我们就把用户注册的功能完成了:
用户登录比用户注册复杂。由于HTTP协议是一种无状态协议,而服务器要跟踪用户状态,就只能通过cookie实现。大多数Web框架提供了Session功能来封装保存用户状态的cookie。
Session的优点是简单易用,可以直接从Session中取出用户登录信息。
Session的缺点是服务器需要在内存中维护一个映射表来存储用户登录信息,如果有两台以上服务器,就需要对Session做集群,因此,使用Session的Web App很难扩展。
我们采用直接读取cookie的方式来验证用户登录,每次用户访问任意URL,都会对cookie进行验证,这种方式的好处是保证服务器处理任意的URL都是无状态的,可以扩展到多台服务器。
由于登录成功后是由服务器生成一个cookie发送给浏览器,所以,要保证这个cookie不会被客户端伪造出来。
实现防伪造cookie的关键是通过一个单向算法(例如MD5),举例如下:
当用户输入了正确的口令登录成功后,服务器可以从数据库取到用户的id,并按照如下方式计算出一个字符串:
"用户id" + "过期时间" + MD5("用户id" + "用户口令" + "过期时间" + "SecretKey")
当浏览器发送cookie到服务器端后,服务器可以拿到的信息包括:
&&& 用户id
&&& 过期时间
如果未到过期时间,服务器就根据用户id查找用户口令,并计算:
MD5("用户id" + "用户口令" + "过期时间" + "SecretKey")
并与浏览器cookie中的MD5进行比较,如果相等,则说明用户已登录,否则,cookie就是伪造的。
这个算法的关键在于MD5是一种单向算法,即可以通过原始字符串计算出MD5,但无法通过MD5反推出原始字符串。
所以登录API可以实现如下:
@post('/api/authenticate')
def authenticate():
i = ctx.request.input()
email = i.email.strip().lower()
password = i.password
user = User.find_first('where email=?', email)
if user is None:
raise APIError('auth:failed', 'email', 'Invalid email.')
elif user.password != password:
raise APIError('auth:failed', 'password', 'Invalid password.')
max_age = 604800
cookie = make_signed_cookie(user.id, user.password, max_age)
ctx.response.set_cookie(_COOKIE_NAME, cookie, max_age=max_age)
user.password = '******'
return user
# 计算加密cookie:
def make_signed_cookie(id, password, max_age):
expires = str(int(time.time() + max_age))
L = [id, expires, hashlib.md5('%s-%s-%s-%s' % (id, password, expires, _COOKIE_KEY)).hexdigest()]
return '-'.join(L)
对于每个URL处理函数,如果我们都去写解析cookie的代码,那会导致代码重复很多次。
利用拦截器在处理URL之前,把cookie解析出来,并将登录用户绑定到ctx.request对象上,这样,后续的URL处理函数就可以直接拿到登录用户:
@interceptor('/')
def user_interceptor(next):
user = None
cookie = ctx.request.cookies.get(_COOKIE_NAME)
if cookie:
user = parse_signed_cookie(cookie)
ctx.request.user = user
return next()
# 解密cookie:
def parse_signed_cookie(cookie_str):
L = cookie_str.split('-')
if len(L) != 3:
return None
id, expires, md5 = L
if int(expires) & time.time():
return None
user = User.get(id)
if user is None:
return None
if md5 != hashlib.md5('%s-%s-%s-%s' % (id, user.password, expires, _COOKIE_KEY)).hexdigest():
return None
return user
return None
这样,我们就完成了用户注册和登录的功能。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具写一个简单的界面很容易,即使是什么都不了解的情况下,这个文本转载了最简单的界面编写,下个文本介绍了TK的简单但具体的应用
在python中创建一个窗口,然后显示出来。from Tkinter import *
root = Tk()
root.mainloop()
就3行就能够把主窗口显示出来了。root是一个变量名称,其代表了这个主窗口。以后创建控件的时候指定控件创建在什么窗口之中,就要用这个root来表示了。而Tk()是一个Tkinter库之中的函数(其实是类的构造函数,构造了一个对象)。而mainloop则是主窗口的成员函数,也就是表示让这个root工作起来,开始接收鼠标的和键盘的操作。你现在就能够通过鼠标缩放以及关闭这个窗口了。注意到窗口的标题是tk,我们可以进行一些修改
root= Tk(className='bitunion')
然后窗口的标题就变成了bitunion了。下面要作的是把这个窗口的内容填充一下,让其有一些东西。先加入一个标签,所谓标签就是一行字。from Tkinter import *
root = Tk(className='bitunion')
label = Label(root)
label['text'] = 'be on your own'
label.pack()
root.mainloop()我们很惊讶的发现窗口变小了,但是其中多了一行字。变小了是因为窗口中已经放了东西了,python的Tkinter非常智能,能够根据内容自动缩放,而不用和传统的windows程序一样,手工的指定绝对坐标了。对于label,它还是一个变量而已。不过这个变量代表了一个标签,也就是那一行字。而这个label的创建是用Label,而Label的参数是root表明了这个控件是root主窗口的成员控件,或者说是子窗口。label['text']表示设置这个标签的text属性为'be
on your own',也就是文字内容了。label.pack和root.mainloop一样费解,但是内涵一样深刻。你现在可以简单理解为把label显示出来的功能,因为你把pack去掉,那你就看不到东西了。其实pack是和控件的布局排版有关西的。再添加一个按钮就能够有更加丰富的内容了,方法是很类似的。看着吧:from Tkinter import *
root = Tk(className='bitunion')
label = Label(root)
label['text'] = 'be on your own'
label.pack()
button = Button(root)
button['text'] = 'change it'
button.pack()
root.mainloop()只不过把button替换了label而Button替换了Label。注意一下Button和Label这些都是Tkinter这些库提供的,而button和Button这样大小写之间的差别仅仅是巧合,你能够随便的给变量取名字,但是Button和Label这些则是需要记住的东西,写代码的时候要经常用到的名字。但是点击按钮你会比较失望,因为并没有什么反应。不过也是当然的事情,你并没有告诉计算机对于这样一个按钮的点击操作需要作出一个什么样的反应来反馈给用户。而这个指定作出什么反应的工作只需要一个行,但是作出具体什么样反应的描述则需要新建一个函数来进行处理。from Tkinter import *
def on_click():
label['text'] = 'no way out'
root = Tk(className='bitunion')
label = Label(root)
label['text'] = 'be on your own'
label.pack()
button = Button(root)
button['text'] = 'change it'
button['command'] = on_click
button.pack()
root.mainloop()button['command'] = on_click表示对于button(按钮)的点击属性用on_click这个函数来处理。而on_click函数也很简洁,只是把label的文本重新设置一下。这个完成了一个事件消息的处理,如果用C来写,需要比这个长更加不好懂的写法。另外你是否会对on_click中出现label这个变量比较奇怪呢?明明在on_click前面没有定义label这个变量啊。如果我在C中这么写程序,编译器一定会告诉我出错的。而python是怎么知道label这个变量存在,然后没有报错的呢?其实python在你写的时候根本就不用知道其是否存在,只是要在运行的时候找得到label就可以了。而运行的前后关系,是通过时间来关联的而不是代码上前后行的关系。这里由于label
= Label(root)先于on_click执行,所以当on_click执行的时候,label就是一个已经定义的变量。如果没有定义呢?那就报告出错喽。最后一个例子:from Tkinter import *
def on_click():
label['text'] = text.get()
root = Tk(className='bitunion')
label = Label(root)
label['text'] = 'be on your own'
label.pack()
text = StringVar()
text.set('change to what?')
entry = Entry(root)
entry['textvariable'] = text
entry.pack()
button = Button(root)
button['text'] = 'change it'
button['command'] = on_click
button.pack()
root.mainloop()
这个就比较复杂了。里面有一个StringVar。这个代表一个字符串,但是跟一般字符串不一样。一般的这样'dfsdf'的字符串是不可变的,你只能把变量指定为不同的字符串,但是字符串本身的内容是不可改变的。而StringVar则是可变的字符串。所以了set和get来设置和取得其内容。主要是entry(单行输入框)要求一个这样的属性来设置和接收其输入框的内容。
用Tkinter实现一个简单的GUI程序,单击click按钮时会在终端打印出’hello world’:
__author__ = 'fyby'
from Tkinter import *
#引入Tkinter工具包
def hello():
print('hello world!')
win = Tk()
#定义一个窗体
win.title('Hello World')
#定义窗体标题
win.geometry('400x200')
#定义窗体的大小,是400X200像素
btn = Button(win, text='Click me', command=hello)
#注意这个地方,不要写成hello(),如果是hello()的话,
#会在mainloop中调用hello函数,
# 而不是单击button按钮时出发事件
btn.pack(expand=YES, fill=BOTH) #将按钮pack,充满整个窗体(只有pack的组件实例才能显示)
mainloop() #进入主循环,程序运行
当我们写一个较大的程序时,最好将代码分成一个或者是几个类,再看一下Hello World例子
#-*- encoding=UTF-8 -*-
__author__ = 'fyby'
from Tkinter import *
class App:
def __init__(self, master):
#构造函数里传入一个父组件(master),创建一个Frame组件并显示
frame = Frame(master)
frame.pack()
#创建两个button,并作为frame的一部分
self.button = Button(frame, text="QUIT", fg="red", command=frame.quit)
self.button.pack(side=LEFT) #此处side为LEFT表示将其放置 到frame剩余空间的最左方
self.hi_there = Button(frame, text="Hello", command=self.say_hi)
self.hi_there.pack(side=LEFT)
def say_hi(self):
print "hi there, this is a class example!"
win = Tk()
app = App(win)
win.mainloop()
看完了上面两个无聊的Hello World例子,再来看一个稍微Perfect点的东西吧。Menu组件,自己画一个像样点的程序外壳。
#-*- encoding=UTF-8 -*-
__author__ = 'fyby'
from Tkinter import *
class App:
def __init__(self, master):
#构造函数里传入一个父组件(master),创建一个Frame组件并显示
frame = Frame(master)
frame.pack()
#创建两个button,并作为frame的一部分
self.button = Button(frame, text="QUIT", fg="red", command=frame.quit)
self.button.pack(side=LEFT) #此处side为LEFT表示将其放置 到frame剩余空间的最左方
self.hi_there = Button(frame, text="Hello", command=self.say_hi)
self.hi_there.pack(side=LEFT)
def say_hi(self):
print "hi there, this is a class example!"
win = Tk()
app = App(win)
win.mainloop()
这个程序还是有点无趣,因为我们只是创建了一个顶级的导航菜单,点击后只是在终端中输出hello而已,下面来创建一个下拉菜单,这样才像一个正儿八经的应用在下面的这个例子中,会创建三个顶级菜单,每个顶级菜单中都有下拉菜单(用add_command方法创建,最后用add_cascade方法加入到上级菜单中去),为每个下拉选项都绑定一个hello函数,在终端中打印出hello.
root.quit是退出这个Tk的实例。
#-*- encoding=UTF-8 -*-
__author__ = 'fyby'
from Tkinter import *
root = Tk()
def hello():
print('hello')
def about():
print('我是开发者')
menubar = Menu(root)
#创建下拉菜单File,然后将其加入到顶级的菜单栏中
filemenu = Menu(menubar,tearoff=0)
filemenu.add_command(label="Open", command=hello)
filemenu.add_command(label="Save", command=hello)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=root.quit)
menubar.add_cascade(label="File", menu=filemenu)
#创建另一个下拉菜单Edit
editmenu = Menu(menubar, tearoff=0)
editmenu.add_command(label="Cut", command=hello)
editmenu.add_command(label="Copy", command=hello)
editmenu.add_command(label="Paste", command=hello)
menubar.add_cascade(label="Edit",menu=editmenu)
#创建下拉菜单Help
helpmenu = Menu(menubar, tearoff=0)
helpmenu.add_command(label="About", command=about)
menubar.add_cascade(label="Help", menu=helpmenu)
root.config(menu=menubar)
mainloop()
写了这一些,差不多对Tkinter有了一个大体的印象了。在Python中用Tkinter绘制GUI界面还是蛮简单的。再把上面的例子扩展一下,和Label标签结合,当单击about的时候,在窗体上打印About的内容,而不是在终端输出。将about函数稍微修改一下。单击about以后将会调用about函数渲染frame绘制一个标签并显示其内容。
def about():
w = Label(root,text="开发者感谢名单\nfuyunbiyi\nfyby尚未出现的女朋友\nhttp://www.programup.com网站")
w.pack(side=TOP)
Tkinter的提供各种控件,如按钮,标签和文本框,一个GUI应用程序中使用。这些控件通常被称为控件或者部件。
目前有15种Tkinter的部件。我们提出这些部件以及一个简短的介绍,在下面的表:
Label widget which can display text and bitmaps标签控件;可以显示文本和位图
按钮控件;在程序中显示按钮
Entry widget which allows to display simple text输入控件;用于显示简单的文本内容
Checkbutton
Checkbutton widget which is either in on- or off-state多选框控件;用于在程序中提供多项选择框
Listbox widget which can display a list of strings.列表框控件;在Listbox窗口小部件是用来显示一个字符串列表给用户
Scale widget which can display a numerical scale范围控件;显示一个数值刻度,为输出限定范围的数字区间
输入控件;与Entry类似,但是可以指定输入范围值
Menu widget which allows to display menu bars, pull-down menus and pop-up menus菜单控件;显示菜单栏,下拉菜单和弹出菜单
Message widget to display multiline text. Obsolete since Label does it too消息控件;用来显示多行文本,与label比较类似
OptionMenu
OptionMenu which allows the user to select a value from a menu.可选菜单控件;允许用户在菜单中选择值
Radiobutton
Radiobutton widget which shows only one of several buttons in on-state单选按钮控件;显示一个单选的按钮状态
Frame widget which may contain other widgets and can have a 3D border框架控件;在屏幕上显示一个矩形区域,多用来作为容器
Toplevel widget, e.g. for dialogs.容器控件;用来提供一个单独的对话框,和Frame比较类似
Text widget which can display text in various forms文本控件;用于显示多行文本
Canvas widget to display graphical elements like lines or text.画布控件;显示图形元素如线条或文本
Container for the properties of an event.事件控件;
标准属性也就是所有控件的共同属性,如大小,字体和颜色等等。
控件大小;
控件颜色;
控件字体;
控件样式;
Tkinter控件有特定的几何状态管理方法,管理整个控件区域组织,一下是Tkinter公开的几何管理类:包、网格、位置
Python GUI之tkinter 常用组件
tkinter中,每个组件都是一个类,创建某个组件其实就是将这个类实例化。在实例化的过程中,可以通过构造函数给组件设置一些属性,同时还必须给该组件指定一个父容器,意即该组件放置何处。最后,还需要给组件...
python GUI 实例
#!/usr/bin/env python3
# coding=utf-8
import tkinter as tk
class Application(tk.Frame):
Python学习笔记-简单GUI开发
使用Tkinter进行开发简单文本窗口实现:下载tkinter模块yum -y install tkinter 最简单的Tkinter窗口from tkinter import *
#将Tkint...
今天终于可以用wxPython开发GUI程序了,非常高兴。把其中的一些注意点写下来以供参考。在windows XP平台下,首先需要做以下环境的配置:
1. 首先是安装python ,安装完之后将py...
写一个简单的界面很容易,即使是什么都不了解的情况下,这个文本转载了最简单的界面编写,下个文本介绍了TK的简单但具体的应用
在python中创建一个窗口,然后显示出来。
#!/usr/bin/python
from Tkinter import *
import sys
class PPCU(object):
def __init__(self):
import java.awt.*;
import java.awt.event.*;
* 创建图形化界面。
* 1.创建frame窗体。
* 2.对窗体进行基本设置。比如大小,位置,布...
一个超级好用的Python GUI框架
没有更多推荐了,刚开始学python 用Tkinter做一个登录界面 遇到一个小问题
[问题点数:40分,结帖人yhb]
本版专家分:0
结帖率 100%
CSDN今日推荐
本版专家分:40
本版专家分:0
匿名用户不能发表回复!
其他相关推荐python如何实现用户登录界面? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。1被浏览<strong class="NumberBoard-itemValue" title="分享邀请回答用Python语言设计GUI界面_百度经验
&&&&&&&&&电脑软件用Python语言设计GUI界面听语音1234567
百度经验:jingyan.baidu.com我们大家都编写过程序,但是如果能够设计一个GUI界面,会使程序增添一个很大的亮点!今天就让我们来用目前十分流行的python语言写出一个最基本的GUI,为日后设计更加漂亮的GUI打下基础。百度经验:jingyan.baidu.comPython编译软件PyQt设计软件百度经验:jingyan.baidu.com1首先,如果没有安装python和PyQt软件的请先直接搜索下载并安装。python是一个开源软件,因此都是可以在网上免费下载的,最新版本即可。下载完成后,我们先打开PyQt designer。2打开后,首先是一个默认的新建窗口界面,在这里我们就选择默认的窗口即可。3现在是一个完全空白的窗口。第一步我们要先把所有的设计元素都拖进这个窗口。我们先拖入一个“Label”,就是一个不可编辑的标签。4随后我们再拖入一个可以编辑的“Line Edit”5最后我们拖入最后一个元素:“PushButton”按钮,也就是平时我们所点的确定。6目前我们已经把所有所需要的元素都拖入了新建的窗口。对于每一个元素,我们都可以双击进行属性值的修改,此时我们仅需要双击改个名字即可7此时我们已经完成了一半,接下来需要对动作信号进行操作。我们需要先切入编辑信号的模式8此时把鼠标移动到任意元素,都会发现其变成红色,代表其被选中。9当我们选中pushbutton后,继续拖动鼠标指向上面的line edit,会发现由pushbutton出现一个箭头指向了line edit,代表pushbutton的动作会对line edit进行操作。10随即会弹出一个配置连接窗口。左边的是pushbutton的操作,我们选择clicked(),即点击pushbutton。11右边是对line edit的操作,我们选择clear(),即清楚line edit中的内容。12最后我们点击确定。13保存完成后,我们在PyQt中的操作就已经完成了。保存的文件名我们命名为test,PyQt生成的设计文件后缀是.ui。14然后我们需要把.ui文件转换成可编译的.py文件,我们需要用到PyQt提供的pyuic4命令来完成转换。这是一个DOS命令,因此我们需要调出DOS操作界面。打开开始菜单,找到附件中的运行。15在运行中输入cmd,确定后即可打开DOS界面。16在DOS界面下,我们需要定位到刚才保存的.ui文件的位置,如果是默认的话,会保存在C:\Python27\Lib\site-packages\PyQt4,定位的过程如图所示。转换成.py文件的命令是:pyuic4 test.ui -o test.py17转换命令执行后,会生成一个test.py的文件,如图所示18最后我们需要对生成的python文件加入头文件和主函数,就可以生成一个完整的GUI程序了!首先是在整个程序的最开头加入import sys,如图所示。19另外,在程序的末尾,加入如图所示的主函数代码。主函数会调用我们再PyQt里已经完成的生成元素的函数以及配置连接函数,因此我们只需要加上主函数来调用他们即可。20保存后,双击我们编辑完成的python文件,就会弹出我们刚才设计的GUI界面啦!这就是我们所完成的第一个用python语言写的GUI程序啦!END百度经验:jingyan.baidu.comPyQt设计完成的文件最好保存在默认路径下,这个路径下才可以执行pyuic4转换命令,否则可能DOS系统下无法识别pyuic4这个命令。经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域),建议您详细咨询相关领域专业人士。作者声明:本篇经验系本人依照真实经历原创,未经许可,谢绝转载。投票(62)已投票(62)有得(1)我有疑问(0)◆◆说说为什么给这篇经验投票吧!我为什么投票...你还可以输入500字◆◆只有签约作者及以上等级才可发有得&你还可以输入1000字◆◆如对这篇经验有疑问,可反馈给作者,经验作者会尽力为您解决!你还可以输入500字相关经验103200热门杂志第1期你不知道的iPad技巧3837次分享第1期win7电脑那些事6679次分享第2期新人玩转百度经验1431次分享第1期Win8.1实用小技巧2670次分享第1期小白装大神1965次分享◆请扫描分享到朋友圈

我要回帖

更多关于 编写一个简单的登录界面 的文章

 

随机推荐