專案準備
- 建立一個資料夾,這裡叫 EXPRESS-AUTH
- npm init -y
啟動服務
- 新建一個server.js 或者 app.js
npm i express
- 開啟埠,啟動服務
// server.js
// 引入 express
const express = require('express')
// 建立伺服器應用程式
const app = express()
app.get('/user', async (req, res) => {
res.send('hello node.js')
})
app.listen(3001, () => {
console.log('http://localhost:3001')
})
複製程式碼
在命令列執行nodemon .\server.js
命令啟動服務
注:nodemon 命令需要全域性安裝 nodemon(npm install --global nodemon
),
在瀏覽器訪問/user時如下,則說明開啟成功
實現簡單的 GET 請求介面
- 建立處理 get 請求的介面
app.get('/api/get', async (req, res) => {
res.send('hello node.js')
})
複製程式碼
- 在vscode商店中下載 REST Client
新建一個 test.http 檔案測試介面,點選
Send Request
傳送請求
// test.http
@url=http://localhost:3001/api
###
get {{url}}/user
複製程式碼
如上圖,get 請求成功
操作 MongoDB 資料庫
- 連線資料庫
- 安裝 mongodb 資料庫
- 在需要啟動的碟符根目錄下新建 data/db 資料夾
- 在命令列對應的碟符下輸入 mongod 命令,即可開啟服務
- 有需要可以下載
NoSQLBooster for MongoDB
軟體
- 建立資料庫模型
npm i mongoose
- 新建 model.js 運算元據庫
// 引入 mongoose
const mongoose = require('mongoose')
// 連線資料庫,自動新建 ExpressAuth 庫
mongoose.connect('mongodb://localhost:27017/ExpressAuth', {
useNewUrlParser: true,
useCreateIndex: true
})
// 建立使用者表
const UserSchema = new mongoose.Schema({
username: {
type: String,
unique: true
},
password: {
type: String,
}
})
// 建立使用者資料庫模型
const User = mongoose.model('User', userSchema)
module.exports = { User }
複製程式碼
簡單的 POST 請求
- 建立處理 POST 請求的介面
// server.js
app.post('/api/register', async (req, res) => {
console.log(req.body);
res.send('ok')
})
app.use(express.json()) // 設定後可以用 req.body 獲取 POST 傳入 data
複製程式碼
- 設定 /api/register
###
POST {{url}}/register
Content-Type: application/json
{
"username": "user1",
"password": "123456"
}
複製程式碼
- 註冊使用者
// server.js
app.post('/api/register', async (req, res) => {
// console.log(req.body);
const user = await User.create({
username: req.body.username,
password: req.body.password
})
res.send(user)
})
複製程式碼
資料庫裡多了一條使用者資料:
密碼 bcrypt 加密
npm i bcrypt
- 在 model.js 中設定密碼入庫前加密,這裡的 hashSync方法接受兩個引數,val 表示傳入的 password,10表示加密的等級,等級越高,所需轉化的時長越長
使用者登入密碼解密
- 在 server.js 中新增處理 /login 的POST請求
app.post('/api/login', async (req, res) => {
const user = await User.findOne({
username: req.body.username
})
if (!user) {
return res.status(422).send({
message: '使用者名稱不存在'
})
}
// bcrypt.compareSync 解密匹配,返回 boolean 值
const isPasswordValid = require('bcrypt').compareSync(
req.body.password,
user.password
)
if (!isPasswordValid) {
return res.status(422).send({
message: '密碼無效'
})
}
res.send({
user
})
})
複製程式碼
登入新增 token
- 安裝 jsonwebtoken
npm i jsonwebtoken
- 引入 jsonwebtoken,自定義金鑰
// 引入 jwt
const jwt = require('jsonwebtoken')
// 解析 token 用的金鑰
const SECRET = 'token_secret'
複製程式碼
- 在登入成功時建立 token
/*
生成 token
jwt.sign() 接受兩個引數,一個是傳入的物件,一個是自定義的金鑰
*/
const token = jwt.sign({ id: String(user._id) }, SECRET)
res.send({
user,
token
})
複製程式碼
這樣我們在傳送請求時,就能看到建立的 token
解密 token 獲取登入使用者
- 先在 server.js 處理 token
app.get('/api/profile', async (req, res) => {
const raw = String(req.headers.authorization.split(' ').pop())
// 解密 token 獲取對應的 id
const { id } = jwt.verify(raw, SECRET)
req.user = await User.findById(id)
res.send(req.user)
})
複製程式碼
- 傳送請求,這裡的請求頭是複製之前測試用的 token
### 個人資訊
get {{url}}/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVjZDI5YjFlMTIwOGEzNDBjODRhNDcwMCIsImlhdCI6MTU1NzM2ODM5M30.hCavY5T6MEvMx9jNebInPAeCT5ge1qkxPEI6ETdKR2U
複製程式碼
服務端返回如下圖,則說明解析成功
本文參考1小時搞定NodeJs(Express)的使用者註冊、登入和授權
配套完整程式碼和註釋見Github