feature: 登录&权限拦截
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
|
||||||
class BaseConfig:
|
class BaseConfig:
|
||||||
@@ -8,6 +9,9 @@ class BaseConfig:
|
|||||||
|
|
||||||
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
|
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
JWT_TOKEN_LOCATION = ["headers", "cookies"]
|
||||||
|
JWT_ACCESS_TOKEN_EXPIRES = timedelta(days=7)
|
||||||
|
|
||||||
|
|
||||||
class DevelopmentConfig(BaseConfig):
|
class DevelopmentConfig(BaseConfig):
|
||||||
"""开发配置"""
|
"""开发配置"""
|
||||||
|
|||||||
@@ -1,8 +1,48 @@
|
|||||||
from flask import Blueprint
|
from flask import Blueprint, make_response, redirect, request
|
||||||
|
from flask_jwt_extended import (
|
||||||
|
create_access_token,
|
||||||
|
create_refresh_token,
|
||||||
|
jwt_required,
|
||||||
|
set_access_cookies,
|
||||||
|
set_refresh_cookies,
|
||||||
|
unset_access_cookies,
|
||||||
|
unset_refresh_cookies,
|
||||||
|
)
|
||||||
|
|
||||||
|
from pear_admin.extensions import db
|
||||||
|
from pear_admin.orms import UserORM
|
||||||
|
|
||||||
passport_api = Blueprint("passport", __name__)
|
passport_api = Blueprint("passport", __name__)
|
||||||
|
|
||||||
|
|
||||||
@passport_api.post("/login")
|
@passport_api.post("/login")
|
||||||
def login_in():
|
def login_in():
|
||||||
return {"message": "登录成功", "code": 0}
|
data = request.get_json()
|
||||||
|
|
||||||
|
user: UserORM = db.session.execute(
|
||||||
|
db.select(UserORM).where(UserORM.username == data["username"])
|
||||||
|
).scalar()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return {"message": "用户不存在", "code": -1}, 401
|
||||||
|
if user.check_password(data["password"]):
|
||||||
|
return {"message": "用户密码错误", "code": -1}, 401
|
||||||
|
|
||||||
|
access_token = create_access_token(user)
|
||||||
|
refresh_token = create_refresh_token(user)
|
||||||
|
|
||||||
|
response = make_response({"code": 0, "message": "登录成功"})
|
||||||
|
|
||||||
|
set_access_cookies(response, access_token)
|
||||||
|
set_refresh_cookies(response, refresh_token)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@passport_api.route("/logout", methods=["GET", "POST"])
|
||||||
|
@jwt_required()
|
||||||
|
def logout():
|
||||||
|
response = make_response(redirect("/login"))
|
||||||
|
unset_access_cookies(response)
|
||||||
|
unset_refresh_cookies(response)
|
||||||
|
return response
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from flask import redirect
|
||||||
from flask_jwt_extended import JWTManager
|
from flask_jwt_extended import JWTManager
|
||||||
|
|
||||||
from pear_admin.orms.user import UserORM
|
from pear_admin.orms.user import UserORM
|
||||||
@@ -14,3 +15,13 @@ def user_identity_lookup(user):
|
|||||||
def user_lookup_callback(_jwt_header, jwt_data):
|
def user_lookup_callback(_jwt_header, jwt_data):
|
||||||
identity = jwt_data["sub"]
|
identity = jwt_data["sub"]
|
||||||
return UserORM.query.filter_by(id=identity).one_or_none()
|
return UserORM.query.filter_by(id=identity).one_or_none()
|
||||||
|
|
||||||
|
|
||||||
|
@jwt.expired_token_loader
|
||||||
|
def expired_token_callback():
|
||||||
|
return redirect("/login")
|
||||||
|
|
||||||
|
|
||||||
|
@jwt.unauthorized_loader
|
||||||
|
def missing_token_callback(error):
|
||||||
|
return redirect("/login")
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
from flask import Blueprint, render_template
|
from flask import Blueprint, render_template
|
||||||
|
from flask_jwt_extended import jwt_required
|
||||||
|
|
||||||
index_bp = Blueprint("index", __name__)
|
index_bp = Blueprint("index", __name__)
|
||||||
|
|
||||||
|
|
||||||
@index_bp.route("/")
|
@index_bp.route("/")
|
||||||
|
@jwt_required()
|
||||||
def index():
|
def index():
|
||||||
return render_template("index.html")
|
return render_template("index.html")
|
||||||
|
|
||||||
|
|
||||||
@index_bp.route("/login.html")
|
@index_bp.route("/login.html")
|
||||||
|
@index_bp.route("/login")
|
||||||
def login():
|
def login():
|
||||||
return render_template("login.html")
|
return render_template("login.html")
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
|
|
||||||
admin.logout(function () {
|
admin.logout(function () {
|
||||||
popup.success("注销成功", function () {
|
popup.success("注销成功", function () {
|
||||||
location.href = "./login.html";
|
location.href = "/api/v1/logout";
|
||||||
});
|
});
|
||||||
|
|
||||||
// 清空 tabs 缓存
|
// 清空 tabs 缓存
|
||||||
|
|||||||
+24
-42
@@ -22,7 +22,7 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="username"
|
name="username"
|
||||||
value=""
|
value="正心全栈编程"
|
||||||
lay-verify="required"
|
lay-verify="required"
|
||||||
placeholder="用户名"
|
placeholder="用户名"
|
||||||
lay-reqtext="请填写用户名"
|
lay-reqtext="请填写用户名"
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
value=""
|
value="123654"
|
||||||
lay-verify="required"
|
lay-verify="required"
|
||||||
placeholder="密 码"
|
placeholder="密 码"
|
||||||
lay-reqtext="请填写密码"
|
lay-reqtext="请填写密码"
|
||||||
@@ -50,50 +50,21 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
|
||||||
<div class="layui-row">
|
|
||||||
<div class="layui-col-xs7">
|
|
||||||
<div class="layui-input-wrap">
|
|
||||||
<div class="layui-input-prefix">
|
|
||||||
<i class="layui-icon layui-icon-vercode"></i>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
name="captcha"
|
|
||||||
value=""
|
|
||||||
lay-verify="required"
|
|
||||||
placeholder="验证码"
|
|
||||||
lay-reqtext="请填写验证码"
|
|
||||||
autocomplete="off"
|
|
||||||
class="layui-input"
|
|
||||||
lay-affix="clear"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-col-xs5">
|
|
||||||
<div style="margin-left: 10px">
|
|
||||||
<img
|
|
||||||
src="https://www.oschina.net/action/user/captcha"
|
|
||||||
onclick="this.src='https://www.oschina.net/action/user/captcha?t='+ new Date().getTime();"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="remember"
|
name="remember"
|
||||||
lay-skin="primary"
|
lay-skin="primary"
|
||||||
title="记住密码"
|
title="记住密码"
|
||||||
|
checked
|
||||||
/>
|
/>
|
||||||
<a href="#forget" style="float: right; margin-top: 7px">忘记密码?</a>
|
<a href="#forget" style="float: right; margin-top: 7px">忘记密码?</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<button
|
<button
|
||||||
class="layui-btn layui-btn-fluid"
|
class="layui-btn layui-btn-fluid login"
|
||||||
lay-submit
|
lay-submit
|
||||||
lay-filter="demo-login"
|
lay-filter="login-in"
|
||||||
>
|
>
|
||||||
登录
|
登录
|
||||||
</button>
|
</button>
|
||||||
@@ -129,20 +100,31 @@
|
|||||||
var form = layui.form;
|
var form = layui.form;
|
||||||
var button = layui.button;
|
var button = layui.button;
|
||||||
var popup = layui.popup;
|
var popup = layui.popup;
|
||||||
|
var $ = layui.$;
|
||||||
|
|
||||||
// 登 录 提 交
|
// 登 录 提 交
|
||||||
form.on("submit(login)", function (data) {
|
form.on("submit(login-in)", function (data) {
|
||||||
/// 验证
|
/// 验证
|
||||||
|
|
||||||
/// 登录
|
|
||||||
|
|
||||||
/// 动画
|
/// 动画
|
||||||
button.load({
|
let btn = button.load({ elem: ".login" });
|
||||||
elem: ".login",
|
|
||||||
time: 1500,
|
/// 登录
|
||||||
done: function () {
|
$.ajax({
|
||||||
|
url: "/api/v1/login",
|
||||||
|
type: "POST",
|
||||||
|
data: JSON.stringify(data.field),
|
||||||
|
contentType: "application/json",
|
||||||
|
success: function (res) {
|
||||||
|
btn.stop(function () {
|
||||||
popup.success("登录成功", function () {
|
popup.success("登录成功", function () {
|
||||||
location.href = "./index.html";
|
location.href = "/";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||||
|
btn.stop(function () {
|
||||||
|
popup.failure(XMLHttpRequest.responseJSON.message);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user