## Process (JWT) User sign in with credentials, then server find matched one and give out a token a session cookie marked httpOnly. ※``token``A JavaScript object: header+body+signature, cause: the server side is stateless. ### Some concept of authentication **Authentication schemes** ([Ref. Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication)) Basic / Bearer / Digest / HOBA / Mutual / AWS4-HMAC-SHA256 Basic authentication: uses Base64 encoding on username and password. Digest authentication: hashes the username and password before sending them over the network. **Authentication methods** API key / JWT / OAuth ### Simple implemention of JWT Check How do JSON Web Tokens work? in [jwt.io](https://jwt.io/introduction/) I used to authenticate by ``Session(Cookie)`` in PHP, but seems that ``Token(jwt)`` is more popular in nodejs project...Also it's more easier to develop an API system to surpport mutiple platform: Desktop applications (Mac/PC), Web (angularJS fronted) and native mobile apps. The beauty of JWT tokens is that they store all of your users claims (including your apps custom user claims) as a JSON object payload inside an encoded string which can be decoded client-side by first splitting the token on ., which breaks it into [ header, payload, sig ] base 64 encoded strings. You can then base 64 decode the payload string and run it through JSON.parse which will produce your claims key-value pairs: ### Generate the token ```js var jwt = require('jsonwebtoken'); // if matched const payload = { user: matchedUser.username } const options = { expiresIn: '2d', issuer: 'https://example.com' } const secret = process.env.JWT_SECRET const token = jwt.sign(payload, secret, options) matchedUser.token=token resolve(this.json(matchedUser)) ``` ### Hand the client the authentication token The signed JWT is placed on a cookie. The cookie is marked httpOnly, which restricts visibility on the client, and its expiration time is set to zero, making it a session-only cookie. ```js const cookieOptions = { httpOnly: true, expires: 0 } res.cookie('twitterAccessJwt', authJwtToken, cookieOptions) ``` The cookie isn't visible to client-side code. ### Authorizing requests ```js // POST Create a new user (only available to logged-in users) // router.post('/db', checkAuthorization, function (req, res, next) { ... } const checkAuthorization = function (req, res, next) { const userJWT = req.cookies.twitterAccessJwt if (!userJWT) { res.send(401, 'Invalid or missing authorization token') } else { const userJWTPayload = jwt.verify(userJWT, jwtConfig.jwtSecret) if (!userJWTPayload) { //Kill the token since it is invalid // res.clearCookie('twitterAccessJwt') res.send(401, 'Invalid or missing authorization token') } else { User.findOne({'twitterAccessToken': userJWTPayload.twitterAccessToken}) .then(function (user) { if (!user) { res.send(401, 'User not currently logged in') } else { console.log('Valid user:', user.name) next() } }) } } } ``` ### Logging the user out ```js //This route logs the user out: //1. Delete the cookie //2. Delete the access key and secret from the user record in mongo // router.get('/logout', checkAuthorization, function (req, res, next) { const userJWT = req.cookies.twitterAccessJwt const userJWTPayload = jwt.verify(userJWT, jwtConfig.jwtSecret) res.clearCookie('twitterAccessJwt') User.findOneAndUpdate({twitterAccessToken: userJWTPayload.twitterAccessToken}, { twitterAccessToken: null, twitterAccessTokenSecret: null }, function (err, result) { if (err) { console.log(err) } else { console.log("Deleted access token for", result.name) } res.render('twitterAccount', {loggedIn: false}) }) }) ``` ### SRC - [Using JWTs for Authentication in RESTful Applications](https://dev.to/perrydbucs/using-jwts-for-authentication-in-restful-applications-55hc) - [Practice Tutorial with express jwt](https://scotch.io/tutorials/authenticate-a-node-es6-api-with-json-web-tokens) - [API Keys vs OAuth Tokens vs JSON Web Tokens](https://zapier.com/engineering/apikey-oauth-jwt/)