auth.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. from flask import Flask, Blueprint, render_template, redirect, flash, url_for, request, abort
  2. from flask_login import login_required, login_user, current_user, logout_user
  3. from flask_mail import Mail
  4. from wtforms import StringField, PasswordField, BooleanField, SubmitField, ValidationError
  5. from wtforms.validators import DataRequired, Length, EqualTo
  6. from typing import Optional
  7. from view.base import App
  8. from core.user import User, load_user_by_email
  9. from flask_wtf import FlaskForm
  10. from send_email import send_msg
  11. auth = Blueprint("auth", __name__)
  12. app: Optional[Flask] = None
  13. mail: Optional[Mail] = None
  14. class LoginForm(FlaskForm):
  15. email = StringField("邮箱", validators=[DataRequired(), Length(1, 32)])
  16. passwd = PasswordField("密码", validators=[DataRequired(), Length(8, 32)])
  17. remember = BooleanField("记住我")
  18. submit = SubmitField("登录")
  19. class RegisterForm(FlaskForm):
  20. email = StringField("邮箱", validators=[DataRequired(), Length(1, 32)])
  21. passwd = PasswordField("密码", validators=[DataRequired(),
  22. EqualTo("passwd_again", message="两次输入密码不相同"),
  23. Length(8, 32)])
  24. passwd_again = PasswordField("重复密码", validators=[DataRequired()])
  25. submit = SubmitField("注册")
  26. def validate_email(self, field):
  27. if load_user_by_email(field.data) is not None:
  28. raise ValidationError("Email already register")
  29. @auth.route('/yours')
  30. @login_required
  31. def yours_page():
  32. msg_count, comment_count, blog_count = current_user.count_info()
  33. return render_template("auth/yours.html", msg_count=msg_count, comment_count=comment_count, blog_count=blog_count)
  34. @auth.route('/login', methods=["GET", "POST"])
  35. def login_page():
  36. if current_user.is_authenticated:
  37. return redirect(url_for("auth.yours_page"))
  38. form = LoginForm()
  39. if form.validate_on_submit():
  40. user = load_user_by_email(form.email.data)
  41. if user is not None and user.check_passwd(form.passwd.data):
  42. login_user(user, form.remember.data)
  43. next_page = request.args.get("next")
  44. if next_page is None or not next_page.startswith('/'):
  45. next_page = url_for('base.index_page')
  46. flash("登陆成功")
  47. return redirect(next_page)
  48. flash("账号或密码错误")
  49. return redirect(url_for("auth.login_page"))
  50. return render_template("auth/login.html", form=form)
  51. @auth.route('/register', methods=["GET", "POST"])
  52. def register_page():
  53. if current_user.is_authenticated:
  54. return redirect(url_for("auth.yours_page"))
  55. form = RegisterForm()
  56. if form.validate_on_submit():
  57. token = User.creat_token(form.email.data, form.passwd.data)
  58. register_url = url_for("auth.confirm_page", token=token, _external=True)
  59. send_msg("注册确认", mail, form.email.data, "register", register_url=register_url)
  60. flash("注册提交成功, 请进入邮箱点击确认注册链接")
  61. return redirect(url_for("base.index_page"))
  62. return render_template("auth/register.html", RegisterForm=form)
  63. @auth.route('/confirm')
  64. def confirm_page():
  65. token = request.args.get("token", None)
  66. if token is None:
  67. abort(404)
  68. return
  69. token = User.load_token(token)
  70. if token is None:
  71. abort(404)
  72. return
  73. if load_user_by_email(token[0]) is not None:
  74. abort(404)
  75. return
  76. User(token[0], token[1], None, None).create_user()
  77. flash(f"用户{token[0]}认证完成")
  78. return redirect(url_for("base.index_page"))
  79. @auth.route('/logout')
  80. def logout_page():
  81. logout_user()
  82. flash("退出登录成功")
  83. return redirect(url_for("base.index_page"))
  84. @auth.context_processor
  85. def inject_base():
  86. return {"top_nav": ["", "", "", "", "", "active"]}
  87. class AuthApp(App):
  88. def __init__(self, import_name):
  89. super(AuthApp, self).__init__(import_name)
  90. global app, mail
  91. app = self._app
  92. mail = self.mail
  93. app.register_blueprint(auth, url_prefix="/auth")
  94. self.login_manager.login_view = "auth.login_page"
  95. @self.login_manager.user_loader
  96. def user_loader(email: str):
  97. return load_user_by_email(email)