From 8ed536247927631bda878155ac0ad65a135d3ec6 Mon Sep 17 00:00:00 2001 From: liuzisheng1 Date: Sat, 6 Jan 2024 03:54:42 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20login=E6=8E=A5=E5=8F=A3=E5=92=8Cref?= =?UTF-8?q?resh-token=E6=8E=A5=E5=8F=A3=EF=BC=8C=E4=BB=A5=E5=8F=8Aev?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 5 ++++ .env.development | 5 ++++ .env.production | 5 ++++ model/user.js | 5 ++-- package.json | 1 + routes/index.js | 65 +++++++++++++++++++++++++++++++++++++++++++++--- routes/user.js | 7 ++++-- utils/login.js | 4 +++ yarn.lock | 5 ++++ 9 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 .env create mode 100644 .env.development create mode 100644 .env.production create mode 100644 utils/login.js diff --git a/.env b/.env new file mode 100644 index 0000000..68585f1 --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +NODE_ENV=development +ACCESS_TOKEN_SECRET=your_access_token_secret_key +REFRESH_TOKEN_SECRET=your_refresh_token_secret_key +ACCESS_TOKEN_EXPIRES_IN=3600 +REFRESH_TOKEN_EXPIRES_IN=86400 diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..5dccbb5 --- /dev/null +++ b/.env.development @@ -0,0 +1,5 @@ +NODE_ENV=development +PORT=3000 +DATABASE_URL=mongodb://localhost:27017/myapp_dev +ACCESS_TOKEN_SECRET=your_access_token_secret_key +REFRESH_TOKEN_SECRET=your_refresh_token_secret_key \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..8e55748 --- /dev/null +++ b/.env.production @@ -0,0 +1,5 @@ +NODE_ENV=production +PORT=8080 +DATABASE_URL=mongodb+srv://user:password@cluster0.mongodb.net/myapp_prod +ACCESS_TOKEN_SECRET=your_access_token_secret_key +REFRESH_TOKEN_SECRET=your_refresh_token_secret_key \ No newline at end of file diff --git a/model/user.js b/model/user.js index 31284ef..572b96a 100644 --- a/model/user.js +++ b/model/user.js @@ -1,7 +1,6 @@ const mongoose = require("./db"); const userSchema = new mongoose.Schema({ - _id: mongoose.Schema.Types.ObjectId, // 用户id username: String, password: String, phone: Number, @@ -15,4 +14,6 @@ const userSchema = new mongoose.Schema({ const userModel = mongoose.model("user", userSchema, "user"); -module.exports = userModel; +module.exports = { + userModel +}; diff --git a/package.json b/package.json index f2efc4e..0f4bb47 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "cookie-parser": "~1.4.4", "cors": "^2.8.5", "debug": "~2.6.9", + "dotenv": "^16.3.1", "express": "~4.16.1", "express-jwt": "^8.4.1", "http-errors": "~1.6.3", diff --git a/routes/index.js b/routes/index.js index a18132f..59340e4 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,11 +1,71 @@ const express = require("express"); const router = express.Router(); - +const { userModel } = require('../model/user'); +const env = require('dotenv').config().parsed; +const jwt = require('jsonwebtoken'); +const { NODE_ENV, + ACCESS_TOKEN_SECRET, + REFRESH_TOKEN_SECRET, + ACCESS_TOKEN_EXPIRES_IN, + REFRESH_TOKEN_EXPIRES_IN + } = env /* GET users listing. */ +router.post("/login", async(req, res) =>{ + const { _id, username, password, phone } = req.body + let user = phone ? await userModel.findOne({ phone }) : + await userModel.findOne({ username }) + if (!user) { + // 这里假设phone也是必填项,用于创建新用户 + await userModel.create({ username, password }); + user = await userModel.findOne({ username }); + } + const accessToken = jwt.sign({ _id: user._id }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: Math.floor(Date.now() / 1000) + Number(process.env.ACCESS_TOKEN_EXPIRES_IN) }); + const refreshToken = jwt.sign({ _id: user._id }, process.env.REFRESH_TOKEN_SECRET, { expiresIn: Math.floor(Date.now() / 1000) + Number(process.env.REFRESH_TOKEN_EXPIRES_IN) }); + if ( user && user.password !== password) { + return res.status(401).json({ code: 401,message: '密码错误',status: "error" }) + } else { + return res.status(200).json({ + code: 200, + message: "登录成功", + status: "success", + result: { + access_token:accessToken, + refresh_token:refreshToken, + expiresIn: Math.floor(Date.now() / 1000) + Number(process.env.ACCESS_TOKEN_EXPIRES_IN), + user + }, + }) + } +}) + +router.post('/refresh-token', async (req, res) => { + const { refresh_token, expiresIn } = req.body + + const decodedRefreshToken = jwt.verify ( refresh_token, process.env.REFRESH_TOKEN_SECRET ); + const user = await userModel.findById ( decodedRefreshToken._id ); + jwt.verify ( refresh_token, REFRESH_TOKEN_EXPIRES_IN, ( err, decodedRefreshToken ) => { + if (err) { + return res.status(403).json({ code: 401,message: '登录过期,请重新登录',status: "error" }) + } + const accessToken = jwt.sign({ _id: decodedRefreshToken._id }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: Math.floor(Date.now() / 1000) + Number(process.env.ACCESS_TOKEN_EXPIRES_IN) }); + return res.status(200).json({ + code: 200, + message: "Token刷新成功", + status: "success", + result: { + expiresIn, + access_token: accessToken, + }, + }) + }) +}) + router.get("/", function (req, res, next) { + res.send({ code: 200, - message: "hello world", + message: "获取成功", + status: "success", result: { name: "张三", age: 18, @@ -13,5 +73,4 @@ router.get("/", function (req, res, next) { }, }); }); - module.exports = router; diff --git a/routes/user.js b/routes/user.js index ecca96a..f3931b3 100644 --- a/routes/user.js +++ b/routes/user.js @@ -1,9 +1,12 @@ -var express = require('express'); -var router = express.Router(); +const express = require('express'); +const router = express.Router(); +const { userModel } = require('../model/user'); + /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); + module.exports = router; diff --git a/utils/login.js b/utils/login.js new file mode 100644 index 0000000..f66a388 --- /dev/null +++ b/utils/login.js @@ -0,0 +1,4 @@ +ACCESS_TOKEN_SECRET=your_access_token_secret_key +REFRESH_TOKEN_SECRET=your_refresh_token_secret_key +ACCESS_TOKEN_EXPIRES_IN=1h // 访问令牌有效期1小时 +REFRESH_TOKEN_EXPIRES_IN=7d // 刷新令牌有效期7天 \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index bf39855..b52f526 100644 --- a/yarn.lock +++ b/yarn.lock @@ -888,6 +888,11 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" +dotenv@^16.3.1: + version "16.3.1" + resolved "https://registry.npmmirror.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + ecdsa-sig-formatter@1.0.11: version "1.0.11" resolved "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" -- Gitee From dbd632999d44cf24821dade680f095b397d038ae Mon Sep 17 00:00:00 2001 From: liuzisheng1 Date: Sat, 6 Jan 2024 03:57:03 +0800 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=E4=BF=AE=E6=94=B9=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routes/index.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/routes/index.js b/routes/index.js index 59340e4..1bfa743 100644 --- a/routes/index.js +++ b/routes/index.js @@ -3,12 +3,6 @@ const router = express.Router(); const { userModel } = require('../model/user'); const env = require('dotenv').config().parsed; const jwt = require('jsonwebtoken'); -const { NODE_ENV, - ACCESS_TOKEN_SECRET, - REFRESH_TOKEN_SECRET, - ACCESS_TOKEN_EXPIRES_IN, - REFRESH_TOKEN_EXPIRES_IN - } = env /* GET users listing. */ router.post("/login", async(req, res) =>{ const { _id, username, password, phone } = req.body @@ -43,7 +37,7 @@ router.post('/refresh-token', async (req, res) => { const decodedRefreshToken = jwt.verify ( refresh_token, process.env.REFRESH_TOKEN_SECRET ); const user = await userModel.findById ( decodedRefreshToken._id ); - jwt.verify ( refresh_token, REFRESH_TOKEN_EXPIRES_IN, ( err, decodedRefreshToken ) => { + jwt.verify ( refresh_token, process.env.REFRESH_TOKEN_EXPIRES_IN, ( err, decodedRefreshToken ) => { if (err) { return res.status(403).json({ code: 401,message: '登录过期,请重新登录',status: "error" }) } -- Gitee