プロジェクト1-Auth
8429 ワード
呑呑呑項目1-Auth
📕Auth
なぜAuth Routeを作成するのですか?
あるサイトに行くと言ったとき、ログインしたユーザーだけが使用できます.
他のページは誰でも使えるという違いがあります
これを検証するためにAuth機能を作成した.
どのように実施するか説明します.
現在、トークンはサーバのuser情報に格納されています.
クライアントのクッキーにも格納
ユーザーがAサイトからBサイトに移動した場合
このユーザがBサイトの権限を持っているかどうか
クライアント上のCookieをサーバに送信して確認する
Cookie内のトークンは符号化状態にあり,サーバが受信したトークンを復号する.
前の記事では、「secretToken」を付けるとuseridが現れるとのこと.
では、そのuseridを使用してそのuseridのDBにタグがあれば、認証が可能です.
順番に説明すると.
こうする
📘作成
私たちが今までルータを作成したとき、このように書いたlogin、signupです.
後でルータが多くなって、どれと関係がある情報を混同するかもしれません
だから今まで私たちが作成したルータはユーザーに関連するルータです.
追加/api/users
次にauthというミドルウェアを使用してミドルウェアフォルダを作成します
以降のフォルダでauth.jsという名前のファイルを作成し、次のコードを書きます.
let auth = (req, res, next) => {
//인증 처리 하는곳
}
module.exports = { auth }
そしてindex上部const { auth } = require('./middleware/auth')
追加が必要今は秋jsファイルでの認証
クライアントからCookieをインポート
前回使ったクッキーパイでいいです.
クッキーを入れる時にx authの名前で入れる
let token = req.cookies.x_auth
こうしてクッキーからコインを出しましたトークン解読
プレイヤーモデルが必要で、プレイヤーモデルを追加させます
const { User } = require('../models/User')
トークンを作成する方法はuserです.jsで作成したようにトークンで検索する方法もuserです.jsで作成するには
userSchema.statics.findByToken = function ( token, cb ){
let user = this
jwt.verify(token, 'secretToken', function(err, decoded){
//userid를 이용해서 확인하기
})
}
jwt.verifyは基本的にjwtが提供する方法ですサイトに詳しい説明があります
簡単に言えば、トークンの作成方法について説明しましたが、言い換えれば
userid+文字列->タグ
だからverifyでタグを入れて、私たちが指定した文字列を入れた後に
コールバック関数が間違っている場合、エラーは、正しい場合、復号値を返す方法です.
useridを使用してユーザーを検索および検証する
復号後の値で現在のdbのuserで検索する方法
userSchema.statics.findByToken = function ( token, cb ){
let user = this
jwt.verify(token, 'secretToken', function(err, decoded){
user.findOne({ "_id": decoded, "token": token }, function (err, user){
if(err) return cb(err)
cb(null, user)
})
})
}
ユーザーでfindOneというモンゴルdbメソッドを使用してユーザーを検索前回とあまり差がないので、理解できるはずです
こうやって仕上げたらauthjsに行って使います
const { User } = require('../models/User')
let auth = (req, res, next) => {
let token = req.cookies.x_auth
User.findByToken(token, (err, user) => {
if(err) throw err
if(!user) return res.json({ isAuth: false, error: true })
req.token = token
req.user = user
next()
})
}
module.exports = { auth }
findByTokenメソッドの使用next()を入れる原因はミドルウェアで、移行がなければ、ずっと閉じ込められています
index.jsのreq.token, req.ユーザー情報を受信可能
app.get('api/users/auth', auth, (req, res) => {
//미들웨어를 통과해 여기까지 왔다는 것은 Auth가 true 라는 의미
})
ここに来たのはAuthがtrueだという意味ですクライアントにこの点を示すコードを追加しましょう.
あなたにユーザー情報を送ります.
ただし、ロールが0の場合は通常のユーザーです.
ゼロ以外の数があれば管理者扱い
app.get('/api/users/auth', auth, (req, res) => {
//미들웨어를 통과해 여기까지 왔다는 것은 Auth가 true 라는 의미
res.status(200).json({
_id: req.user._id,
isAdmin: req.user.role === 0 ? false : true,
isAuth: true,
email: req.user.email,
name: req.user.name,
role: req.user.role,
image: req.user.image
})
})
こうしてコードを作った次にPostmanで確認します
こんなによく見える
📗コード#コード#
auth.js
const { User } = require('../models/User')
let auth = (req, res, next) => {
let token = req.cookies.x_auth
User.findByToken(token, (err, user) => {
if(err) throw err
if(!user) return res.json({ isAuth: false, error: true })
req.token = token
req.user = user
next()
})
}
module.exports = { auth }
user.jsconst mongoose = require('mongoose')
const bcrypt = require('bcrypt')
const saltRounds = 10
const jwt = require('jsonwebtoken')
const userSchema = mongoose.Schema({
name: {
type: String,
maxlength: 50
},
email: {
type: String,
trim: true,
unique: 1
},
password: {
type: String,
minlength: 5
},
role: {
type: Number,
default: 0
},
image: String,
token: {
type: String
},
tokenExp:{
type: Number
}
})
userSchema.pre('save', function(next){
let user = this;
if (user.isModified('password')){
bcrypt.genSalt(saltRounds, function (err, salt) {
if(err) return next(err)
bcrypt.hash(user.password, salt, function (err, hash){
if(err) return next(err)
user.password = hash
next()
})
})
} else {
next()
}
})
userSchema.methods.comparePassword = function(plainPassword, cb) {
bcrypt.compare(plainPassword, this.password, function(err, isMatch) {
if(err) return cb(err)
cb(null, isMatch)
})
}
userSchema.methods.generateToken = function(cb){
let user = this
let token = jwt.sign(user._id.toHexString(), 'secretToken');
user.token = token
user.save(function(err, user){
if(err) return cb(err)
cb(null, user)
})
}
userSchema.statics.findByToken = function ( token, cb ){
let user = this
jwt.verify(token, 'secretToken', function(err, decoded){
user.findOne({ "_id": decoded, "token": token }, function (err, user){
if(err) return cb(err)
cb(null, user)
})
})
}
const User = mongoose.model('User', userSchema)
module.exports = { User }
index.jsconst express = require('express')
const app = express()
const port = 3000
const mongoose = require('mongoose')
const bodyParser = require('body-parser')
const config = require('./config/key')
const cookieParser = require('cookie-parser')
const { auth } = require('./middleware/auth')
const { User } = require("./models/User")
app.use(bodyParser.urlencoded({extended: true}))
app.use(bodyParser.json())
app.use(cookieParser())
mongoose.connect(config.mongoURI
).then( () => console.log('MongoDB Connected'))
.catch(err => console.log(err))
app.get('/', (req, res) => {
res.send('Hello World! BooKi')
})
app.post('/api/users/signup', (req, res) => {
//회원 가입 할 때 작성한 정보들을 가져와 DB에 넣어준다
const user = new User(req.body)
user.save((err, userInfo) => {
if (err) return res.json({ success: false, err})
return res.status(200).json({
success: true
})
})
})
app.post('/api/users/login', (req, res) => {
User.findOne({ email: req.body.email }, (err, user) => {
if(!user) {
return res.json({
loginSuccess: false,
message: "해당 이메일에 해당하는 유저가 없습니다."
})
}
user.comparePassword(req.body.password, (err, isMatch) => {
if(!isMatch){
return res.json({
loginSuccess: false,
message: "비밀번호가 틀렸습니다."
})
}
user.generateToken((err, user) => {
if(err) {
return res.status(400).send(err)
}
res.cookie("x_auth", user.token)
.status(200)
.json({
loginSuccess: true,
userId: user._id
})
})
})
})
})
app.get('/api/users/auth', auth, (req, res) => {
//미들웨어를 통과해 여기까지 왔다는 것은 Auth가 true 라는 의미
res.status(200).json({
_id: req.user._id,
isAdmin: req.user.role === 0 ? false : true,
isAuth: true,
email: req.user.email,
name: req.user.name,
role: req.user.role,
image: req.user.image
})
})
app.listen(port, () => {
console.log(`http://localhost:${port}/`)
})
Reference
この問題について(プロジェクト1-Auth), 我々は、より多くの情報をここで見つけました https://velog.io/@qnrl3442/프로젝트-1-Authテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol