JWTの知識点と操作


1.JWTとは何ですか
  • JSON Web Tokenは、オープン基準(RFC 7519)
  • である.
  • は、各当事者間の情報をJSONオブジェクトとして安全に伝送することができるコンパクトかつ独立した方法を定義している.
  • この情報は、デジタル署名された
  • であるので、検証および信頼できる.
    2.JWT構成
    'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiemoiLCJpYXQiOjE1NjY1Mjc1ODB9.zp0xQbQQcK-xn7wDXFBEi64sNPqnhDCNCLh0QyqP8zI'
    
  • ヘッド
  • ペイロード
  • 署名(Signature)
  • base 64 UrlEnccodeコードを使用しています.
    2.1ヘッダ
  • typ:tokenのタイプ、ここで固定ビットJWT
  • alg:HMAC SHA 256またはRSA
  • などのhashアルゴリズムを使用する.
    2.2ペイロード
  • は、転送が必要な情報、例えばユーザ名
  • を記憶する.
  • には、期限切れなどのメタデータも含まれています.発表者
  • はヘッドと違って、Payloadは暗号化されてもいいです.
    2.3署名
  • は、HeaderとPayloadの部分に署名(暗号化)を行う
  • .
  • は、Tokenが転送中に改竄または損傷されていないことを保証する.
    3 koaで操作するjwt
    3.1 Jsonwebtokenをインストールする
    npm i jsonwebtoken -S
    
    3.2 jsonwebtoken署名
    const jwt = require('jsonwebtoken')
    const token = jwt.sign({name: 'zj'}, 'secret')
    // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiemoiLCJpYXQiOjE1NjY1Mjc1ODB9.zp0xQbQQcK-xn7wDXFBEi64sNPqnhDCNCLh0QyqP8zI'
    
    3.3 Jsonwebtoken検証
    const sign = jwt.verify(token, 'secret')
    // { name: 'zj', iat: 1566527580 }
    
    3.4カスタムjwtミドルウェア
    const jsonwebtoken = require('jsonwebtoken')
    const auth = async (ctx, next) => {
    	const { authorization = '' } = ctx.request.header
    	const token = authorization.replace('Bearer ', '')
    	try {
    		const user = jsonwebtoken.verify(token, secret)
    		ctx.state.user = user
    	} catch (e) {
    		ctx.throw(401, e.message)
    	}
    	await next()
    }
    ...
    router.del('/:id', auth, del)
    
    3.5カスタムjwtミドルウェアの代わりにkoa-jwtを使用する
    const jwt = require('koa-jwt')
    const auth = jwt({secret})
    ...
    router.del('/:id', auth, del)
    
    3.6ログインしてtokenに戻る
    //     
    ...
    const token = jsonwebtoken.sign({name,  _id}, secret, {expiresIn: '1d'}) // expiresIn     1 
    ctx.body = { token }
    
    3.7登録者とjwt情報が一致しているか確認する
    async checkOwner (ctx, next) {
        if (ctx.params.id !== ctx.state.user._id) {
            ctx.throw(403, '    ')
        }
        await next()
    }
    ...
    router.del('/:id', auth, checkOwner, del)