diff --git a/.env b/.env new file mode 100644 index 0000000000000000000000000000000000000000..68585f1aa4f071003ccf438e6b83a90e4b6b6581 --- /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 0000000000000000000000000000000000000000..5dccbb5bfc0b07d1bc6afecc900f97110a390d18 --- /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 0000000000000000000000000000000000000000..8e55748fe1fe9407e567081e7b865de35c76d1d6 --- /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 31284ef9ee21bcc835e3d5a048d71ccb780f5a9f..572b96a975869ab3833e0e97f23821e3d448b6f8 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 f2efc4ef12c55923b65d94e52153ec7798339dac..0f4bb4703298101e6c53ef320cc108acd14f2896 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 a18132fa886d68c943cf8dbd73400fdf10f328b3..1bfa7431470cc5ae3e079ca90cf9f89138a7ae41 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,11 +1,65 @@ const express = require("express"); const router = express.Router(); - +const { userModel } = require('../model/user'); +const env = require('dotenv').config().parsed; +const jwt = require('jsonwebtoken'); /* 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, process.env.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 +67,4 @@ router.get("/", function (req, res, next) { }, }); }); - module.exports = router; diff --git a/routes/user.js b/routes/user.js index ecca96a56b309a315ddf6399155fd2f953031d3b..f3931b38108107c95bcb52b7b170d6bbbbefb07b 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 0000000000000000000000000000000000000000..f66a3883a91eab6691f24fb04968f4632cbcb74e --- /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 bf398554e8128b62627bfd210366f8130477e777..b52f526048e3467496858983396e0b6b4f657462 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"