Maison  >  Article  >  développement back-end  >  Utiliser Python pour implémenter les fonctions de connexion et d'enregistrement des utilisateurs Web

Utiliser Python pour implémenter les fonctions de connexion et d'enregistrement des utilisateurs Web

不言
不言original
2018-04-09 17:28:2213494parcourir

Cet article présente principalement le tutoriel d'utilisation de Python pour implémenter les fonctions de connexion et d'enregistrement des utilisateurs Web. Les amis qui en ont besoin peuvent s'y référer

La gestion des utilisateurs est un problème que la plupart des sites Web doivent résoudre. La gestion des utilisateurs implique l'enregistrement et la connexion des utilisateurs.

L'enregistrement des utilisateurs est relativement simple. Nous pouvons d'abord implémenter la fonction d'enregistrement des utilisateurs via l'API :

_RE_MD5 = re.compile(r'^[0-9a-f]{32}$')

@api
@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)
 if user:
  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

Notez que le mot de passe de l'utilisateur est le client La chaîne de hachage de 32 bits transmise par le serveur est calculée par MD5, de sorte que le serveur ne connaît pas le mot de passe d'origine de l'utilisateur.

Ensuite, vous pouvez créer une page d'inscription, laisser les utilisateurs remplir le formulaire d'inscription, puis soumettre les données à l'API de l'utilisateur enregistré :

{% extends '__base__.html' %}

{% block title %}注册{% endblock %}

{% block beforehead %}

<script>
function check_form() {
 $(&#39;#password&#39;).val(CryptoJS.MD5($(&#39;#password1&#39;).val()).toString());
 return true;
}
</script>

{% endblock %}

{% block content %}

<p class="uk-width-2-3">
 <h1>欢迎注册!</h1>
 <form id="form-register" class="uk-form uk-form-stacked" onsubmit="return check_form()">
  <p class="uk-alert uk-alert-danger uk-hidden"></p>
  <p class="uk-form-row">
   <label class="uk-form-label">名字:</label>
   <p class="uk-form-controls">
    <input name="name" type="text" class="uk-width-1-1">
   </p>
  </p>
  <p class="uk-form-row">
   <label class="uk-form-label">电子邮件:</label>
   <p class="uk-form-controls">
    <input name="email" type="text" class="uk-width-1-1">
   </p>
  </p>
  <p class="uk-form-row">
   <label class="uk-form-label">输入口令:</label>
   <p class="uk-form-controls">
    <input id="password1" type="password" class="uk-width-1-1">
    <input id="password" name="password" type="hidden">
   </p>
  </p>
  <p class="uk-form-row">
   <label class="uk-form-label">重复口令:</label>
   <p class="uk-form-controls">
    <input name="password2" type="password" maxlength="50" placeholder="重复口令" class="uk-width-1-1">
   </p>
  </p>
  <p class="uk-form-row">
   <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-user"></i> 注册</button>
  </p>
 </form>
</p>

{% endblock %}
Try

De cette manière, nous avons complété la fonction d'enregistrement des utilisateurs :

2015430102634859.jpg (560×753)

La connexion des utilisateurs est plus compliquée que l'enregistrement des utilisateurs. Étant donné que le protocole HTTP est un protocole sans état et que le serveur souhaite suivre le statut de l'utilisateur, cela ne peut être réalisé que via des cookies. La plupart des frameworks Web fournissent une fonctionnalité de session pour encapsuler les cookies qui enregistrent l'état de l'utilisateur.

L'avantage de Session est qu'il est simple et facile à utiliser, et les informations de connexion de l'utilisateur peuvent être récupérées directement depuis Session.

L'inconvénient de Session est que le serveur doit conserver une table de mappage en mémoire pour stocker les informations de connexion de l'utilisateur. S'il y a plus de deux serveurs, Session doit être regroupée. Par conséquent, l'application Web utilisant Session est difficile. pour s'étendre.

Nous utilisons la méthode de lecture directe des cookies pour vérifier la connexion de l'utilisateur. Chaque fois qu'un utilisateur accède à une URL, le cookie sera vérifié. L'avantage de cette méthode est de garantir que le serveur traite toute URL sans état. manière. Peut être étendu à plusieurs serveurs.

Étant donné que le serveur génère un cookie et l'envoie au navigateur après une connexion réussie, il est nécessaire de s'assurer que ce cookie ne sera pas falsifié par le client.

La clé de la mise en œuvre des cookies anti-contrefaçon réside dans un algorithme unidirectionnel (tel que MD5), par exemple :

Lorsque l'utilisateur saisit le mot de passe correct et se connecte avec succès, le serveur peut récupérer l'utilisateur à partir de l'identifiant de la base de données et calculer une chaîne comme suit :

"ID utilisateur" + "Délai d'expiration" + MD5("ID utilisateur" + "Mot de passe utilisateur" + "Délai d'expiration" + " SecretKey")

Lorsque le navigateur envoie un cookie au serveur, les informations que le serveur peut obtenir comprennent :

  • ID utilisateur

  • Délai d'expiration

  • Valeur MD5

Si le délai d'expiration n'a pas expiré, le serveur recherche le mot de passe de l'utilisateur en fonction de l'utilisateur id et calcule :

MD5("User ID" + "User Password" + "Expiration Time" + "SecretKey")

et comparez-le avec le MD5 dans le cookie du navigateur s'ils. sont égaux, l'utilisateur s'est connecté, sinon le cookie est faux.

La clé de cet algorithme est que MD5 est un algorithme unidirectionnel, c'est-à-dire que MD5 peut être calculé à partir de la chaîne d'origine, mais la chaîne d'origine ne peut pas être déduite de MD5.

Ainsi, l'API de connexion peut être implémentée comme suit :

@api
@post(&#39;/api/authenticate&#39;)
def authenticate():
  i = ctx.request.input()
  email = i.email.strip().lower()
  password = i.password
  user = User.find_first(&#39;where email=?&#39;, email)
  if user is None:
    raise APIError(&#39;auth:failed&#39;, &#39;email&#39;, &#39;Invalid email.&#39;)
  elif user.password != password:
    raise APIError(&#39;auth:failed&#39;, &#39;password&#39;, &#39;Invalid password.&#39;)
  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 = &#39;******&#39;
  return user

# 计算加密cookie:
def make_signed_cookie(id, password, max_age):
  expires = str(int(time.time() + max_age))
  L = [id, expires, hashlib.md5(&#39;%s-%s-%s-%s&#39; % (id, password, expires, _COOKIE_KEY)).hexdigest()]
  return &#39;-&#39;.join(L)

对于每个URL处理函数,如果我们都去写解析cookie的代码,那会导致代码重复很多次。

利用拦截器在处理URL之前,把cookie解析出来,并将登录用户绑定到ctx.request对象上,这样,后续的URL处理函数就可以直接拿到登录用户:

@interceptor(&#39;/&#39;)
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):
  try:
    L = cookie_str.split(&#39;-&#39;)
    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(&#39;%s-%s-%s-%s&#39; % (id, user.password, expires, _COOKIE_KEY)).hexdigest():
      return None
    return user
  except:
    return None
Try

De cette façon, nous avons terminé les fonctions d'enregistrement et de connexion des utilisateurs .

Recommandations associées :

Un résumé de plusieurs façons de connecter des chaînes en python

Explication détaillée de la méthode de tri dans python

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn