PageRenderTime 30ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/view/index.py

https://gitlab.com/xiaok/SaltAdmin
Python | 237 lines | 233 code | 1 blank | 3 comment | 1 complexity | 0f3c4ae54497e0b3ffcfc452189bfdcb MD5 | raw file
  1. #!/usr/bin/env python
  2. #-*- coding:utf-8 -*-
  3. from main import *
  4. import time
  5. import random
  6. import urllib2
  7. import json
  8. #import os
  9. def genToken(L):
  10. CharLib = map(chr,range(97,123)+range(65,91)+range(48,58))
  11. Str = []
  12. for i in range(L):
  13. Str += random.sample(CharLib,1)
  14. return ''.join(Str)
  15. # 加密UID
  16. def encryptUID(id):
  17. key = 'db884468559f4c432bf1c1775f3dc9da'
  18. return key + str(id)
  19. # 解密SID
  20. def decryptUID(uStr):
  21. return int(uStr.split('a')[1])
  22. # 获取cookies
  23. def getCookie(name):
  24. ck = web.cookies()
  25. if ck.get(name):
  26. return ck.get(name)
  27. else:
  28. return None
  29. # 创建会话
  30. def genSession(SID,Username,ShowName,LastIP,LastLocation,LastDate,Token,Lstat,kpl):
  31. LoginDate = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
  32. Expiry = 86400
  33. session = web.config._session
  34. session.isLogin = True
  35. session.SID = SID
  36. session.Username = Username
  37. session.ShowName = ShowName
  38. session.LastLocation = LastLocation
  39. # 登录是否正常返回
  40. if Lstat == 'ok':
  41. session.Lstat = '正常'
  42. elif Lstat == 'other':
  43. session.Lstat = '您的上次登录在别的电脑或者别的浏览器'
  44. else:
  45. session.Lstat = '未知'
  46. # 获取客户端信息
  47. #print 'HTTP_ENV: '
  48. #print web.ctx.environ #来源地址
  49. #print 'HTTP_REFERER: '
  50. #print web.ctx.env.get('HTTP_REFERER', 'http://google.com')
  51. #LoginHost = web.ctx.ip #这两种方法都能获取到客户端IP
  52. LoginHost = web.ctx.environ['REMOTE_ADDR']
  53. Agent = web.ctx.environ['HTTP_USER_AGENT']
  54. # 测试解析
  55. #LoginHost = '119.122.181.82'
  56. # 本次登录地点判断
  57. Location = 'Localhost'
  58. ip = LoginHost.split('.')
  59. if ip[0]+ip[1] in ['17216','192168','1270'] or ip[0] == '10':
  60. Location = '本地局域网'
  61. else:
  62. # 这里要从公网去解析
  63. url = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=" + LoginHost
  64. response = urllib2.urlopen(url)
  65. rt = json.load(response)
  66. if rt['ret'] == 1 :
  67. Location = rt['province'] + rt['city'] + ' [' + rt['isp'] + ']'
  68. else:
  69. Location = 'unkown'
  70. # 登录日志写入数据库
  71. if not Token:
  72. # Token用来判断是否输入的用户名登录验证的还是从token验证过来的
  73. Token = genToken(32)
  74. if kpl == 'no':
  75. Expiry = 0 # 不记住登录设置数据库里存储的token的过期时间与登录时间相等
  76. #db.query('''update users set loginhost="%s",logindate="%s" where id="%s"''' % (LoginHost,LoginDate,SID))
  77. db.query('''insert into login_logs (uid,ip,location,agent,token,expiry) values ("%s","%s","%s","%s","%s",NOW() + INTERVAL %d SECOND)''' % (SID,LoginHost,Location,Agent,Token,Expiry))
  78. db.query('''update users set loginfo=(select id from login_logs where uid="%s" and ip="%s" and token="%s" and status="yes" order by id desc limit 1) where id="%s"''' % (SID,LoginHost,Token,SID))
  79. # 写入token到session存储于服务器端
  80. session.Token = Token
  81. # 写入uid和token到cookies存储于客户端
  82. #web.setcookie('Username', Username, Expiry)
  83. #用uid伪装成Username存储在cookies中
  84. web.setcookie('Username', encryptUID(SID), Expiry)
  85. web.setcookie('Token', Token, Expiry)
  86. # 写入上次登录日期和IP到session
  87. if LastDate:
  88. # 格式化日期加上年月日在前台显示如果为None表示用户是第一次登录
  89. session.LastDate = time.strftime('%Y-%m-%d %H:%M:%S',time.strptime(str(LastDate),'%Y-%m-%d %H:%M:%S'))
  90. else:
  91. session.LastDate = '第一次登录'
  92. session.LastIP = LastIP
  93. # 写入当前登录日期和IP到数据库设计说明
  94. # 1.如果用户登录成功就会从数据库获取上次登录的时间和IP并写入session然后立马把本次登录的IP和时间更新到数据库
  95. # 2.还有一种方法就是用户登录时把本次登录的时间和IP写入session而先不动数据库里的记录直到用户执行正常退出操作时再把session里存储的本次登录的信息写入数据库
  96. # 3.第1个方法和第2个方法记录的数据是相反的为什么不用第2种呢因为万一用户不是正常退出呢那数据库就不会更新本次登录的信息所以...
  97. # By Luxiaok 2014年4月7日 22:49:00
  98. # 登录成功,这里执行DB操作应该要有异常处理的
  99. # return True
  100. class Login:
  101. def GET(self,*args):
  102. # URL做了多项正则匹配要进行参数冗余处理还不知道为什么url正则后会给GET传个参数进来
  103. # 多余的参数就是匹配的url后缀
  104. #print "Self =",self
  105. #print "Args =",args
  106. uid = getCookie('Username')
  107. token = getCookie('Token')
  108. sid = getCookie('xk_session')
  109. HTTP_REFERER = getCookie('HTTP_REFERER')
  110. #print 'Login referer from cookie: ',HTTP_REFERER
  111. if uid and token:
  112. #print 'uid =',uid
  113. #print 'token =',token
  114. #print 'sid =',sid
  115. uid = decryptUID(uid)
  116. try:
  117. g = db.query('''
  118. select U.id,U.username,U.nickname,U.loginfo,L.id as LID,L.ip,L.date from login_logs as L
  119. left join users as U on L.uid=U.id
  120. where U.id="%s" and L.token="%s" and L.status="yes" and L.expiry>now() and U.status="yes"''' % (uid,token))
  121. except Exception,e:
  122. print "MySQL Error: ",Exception,":",e
  123. return "Database Error"
  124. if g:
  125. d = g[0]
  126. Username = d.username
  127. Lstat = 'ok' #是否异常登录反馈
  128. if not d.nickname:
  129. ShowName = d.username
  130. else:
  131. ShowName = d.nickname
  132. if d.loginfo != d.LID:
  133. g2 = db.query('''select L.ip,L.date from users as U left join login_logs as L on U.loginfo=L.id where U.id="%s"''' % uid)
  134. d = g2[0]
  135. # 这里还可以返回一个异地浏览器登录的提示
  136. Lstat = "other" #上次登录在别的浏览器或者异地异机
  137. LastIP = d.ip
  138. LastDate = d.date
  139. genSession(uid,Username,ShowName,LastIP,LastDate,token,Lstat,kpl='yes')
  140. if HTTP_REFERER:
  141. web.setcookie('HTTP_REFERER', '88888888', -1000)
  142. return web.seeother(HTTP_REFERER)
  143. else:
  144. return web.seeother("/dashboard")
  145. else:
  146. # 如果数据库里存储的token状态为no即用户已经正常退出会话无效了那么清除本地cookies
  147. web.setcookie('Username', '88888888', -1)
  148. web.setcookie('Token', '88888888', -1)
  149. if getLogin():
  150. #用户已登录
  151. return web.seeother("/dashboard")
  152. else:
  153. #用户未登录
  154. return render.login()
  155. def POST(self,*args):
  156. getPost = web.input()
  157. #kpl = getPost.kpl # 是否记住登录
  158. try:
  159. getSQL = db.query('''select u.id,u.username,u.password,u.nickname,u.status,L.ip,L.location,L.date from users as u left join login_logs as L on u.loginfo=L.id where username="%s" and password=md5("%s")''' % (getPost.username,getPost.password))
  160. except:
  161. # 服务器(数据库)错误
  162. web.header('Content-Type', 'application/json')
  163. return json.dumps({'code':-1,'msg':'数据库错误'})
  164. if getSQL:
  165. # 获取登录数据
  166. getData = getSQL[0]
  167. SID = getData['id']
  168. Username = getData['username']
  169. Status = getData['status']
  170. ShowName = getData['nickname']
  171. LastDate = getData['date']
  172. LastIP = getData['ip']
  173. LastLocation = getData['location']
  174. if not ShowName:
  175. ShowName = Username
  176. if Status == 'yes':
  177. # 符合登录要求登录数据写入session创建会话
  178. genSession(SID,Username,ShowName,LastIP,LastLocation,LastDate,False,Lstat='ok',kpl=getPost.kpl)
  179. #HTTP_REFERER = getCookie('HTTP_REFERER')
  180. #if HTTP_REFERER:
  181. # web.setcookie('HTTP_REFERER', '88888888', -1000)
  182. # return web.seeother(HTTP_REFERER)
  183. #else:
  184. # web.setcookie('HTTP_REFERER', '88888888', -1000)
  185. # return web.seeother("/dashboard")
  186. web.header('Content-Type', 'application/json')
  187. return json.dumps({'code':0,'msg':'Success'}) # 登录成功
  188. else:
  189. # 用户被禁用
  190. web.header('Content-Type', 'application/json')
  191. return json.dumps({'code':-2,'msg':'用户已被禁用'})
  192. else:
  193. # 用户名或密码错误
  194. web.header('Content-Type', 'application/json')
  195. return json.dumps({'code':-3,'msg':'用户名或密码错误'})
  196. class Logout:
  197. def GET(self):
  198. uid = getCookie('Username')
  199. token = getCookie('Token')
  200. sidName = getCookie('xk_session')
  201. if uid and token and sidName:
  202. uid = decryptUID(uid)
  203. #sfile = 'session/' + sidName
  204. # 删除会话文件貌似kill方法会把sessionID文件干掉
  205. #try:
  206. # os.remove(sfile)
  207. #except Exception,e:
  208. # print "Session File Error: ",Exception,":",e
  209. # 设置cookies的status为no
  210. try:
  211. db.query('''update login_logs set status="no" where uid="%s" and token="%s"''' % (uid,token))
  212. except Exception,e:
  213. print "MySQL Error: ",Exception,":",e
  214. web.setcookie('Username', '88888888', -1)
  215. web.setcookie('Token', '88888888', -1)
  216. web.config._session.kill()
  217. raise web.seeother("/")
  218. # 测试页面
  219. class Test:
  220. def GET(self):
  221. if getLogin():
  222. SID = getLogin()['SID']
  223. ShowName = getLogin()['ShowName']
  224. #print "ShowName: " + ShowName
  225. return render.test(ShowName=ShowName,uid=SID)
  226. else:
  227. return web.seeother("/login")