nodejs + express + express-session + redis

nodejs + express + express-session + redishtml

標題彷佛又是不太對,你們領會精神哈前端

Express

安裝express-generator,而後用它來建立一個工程;node

npm install express-generator -g
express myApp
cd myApp
npm install
npm start 或是 node bin/www

訪問 http://localhost:3000/ 便可看到Express的字樣;redis

Express Generator搭建HTTPS前端框架 - 簡書mongodb

Session

在 express中操做 session要用到 express-session這個模塊,主要的方法就是 session(options),
其中 options爲JSON對象,包含可選參數,主要有:數據庫

name: 設置 cookie 中,保存 session 的字段名稱,默認爲 connect.sid 。
store: session 的存儲方式,默認存放在內存中,也可使用 redis,mongodb 等。express 生態中都有相應模塊的支持。
secret: 經過設置的 secret 字符串,來計算 hash 值並放在 cookie 中,使產生的 signedCookie 防篡改。
cookie: 設置存放 session id 的 cookie 的相關選項,默認爲(default: { path: '/', httpOnly: true, secure: false, maxAge: null })
genid: 產生一個新的 session_id 時,所使用的函數, 默認使用 uid2 這個 npm 包。
rolling: 每一個請求都從新設置一個 cookie,默認爲 false。
resave: 即便 session 沒有被修改,也保存 session 值,默認爲 true。express

在原有項目中添加代碼npm

app.jsjson

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var session = require('express-session');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(session({ secret: 'recommand 128 bytes random string', // 建議使用 128 個字符的隨機字符串
  cookie: { maxAge: 60 * 1000 } }));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

session須要在 route以前 use;segmentfault

 

routes/users.js

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  if(req.session.isVisit) {
    req.session.isVisit++;
    res.send('<p>第 ' + req.session.isVisit + ' 次來此頁面</p>');
  } else {
    req.session.isVisit = 1;
    res.send("<p>歡迎第 1 次來此頁面</p>"); }
});

module.exports = router;

Session中添加了 isVisit字段。

cookie 和 session - Node.js 實戰心得 - 極客學院Wiki

Redis

session 存放在內存中不方便進程間共享,所以可使用 redis 等緩存來存儲 session。

使用 redis 做爲緩存,可使用 connect-redis 模塊來獲得 redis 鏈接實例,而後在 session 中設置存儲方式爲該實例。

剛纔的app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var session = require('express-session');
var redisStore = require('connect-redis')(session);

const redis = require('redis');
const client = redis.createClient(6379, 'IP', {auth_pass: 'password'});

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(session({ store: new redisStore({
    client: client,
    prefix: 'session:'
  }),
  secret: 'recommand 128 bytes random string' }));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

Session -> redisStore -> client,依次依賴

 

redis - npm

connect-redis - npm

nodejs+express+express-session+redis 實現登錄驗證 - 風中追風 - SegmentFault 思否

 

這些都是扯淡,用的時候一點兒也很差用,對於先後端分離形成的跨域問題簡直是一籌莫展;

最後都改爲了用token,就像這樣:

方案一:使用token
1.前端把account和password,提交到服務端的登陸api

2.服務端驗證正確後,生成一個token,並把token和userId,存在緩存裏(推薦redis數據庫),而後把token返回給前端。

3.前端每次的請求頭中帶token,這樣就可以輕鬆的實現

 

方案二:使用cookie

1.client發送username和password到server

2.server驗證成功後, 寫cookie到client,而後返回ok的json, 其中cookie的key要存儲在redis中,value就是用戶信息, 而且要設置key的超時時間,如:60分鐘

3.client收到ok後, 進行相應的業務操做, 之後每次請求server都會自動帶上cookie, 不用你寫代碼

4.server端的filter(你確定用filter來實現)中會每次驗證傳過來的cookie的key在redis中是否存在, 有就表明登陸成功過能夠操做, 沒有就返回錯誤標識注意: 在登陸成功後, 每次調用服務器接口時候, 都要爲redis的key進行續期,如60分鐘

5.當redis的key超過60分鐘, 本身會刪除這個key, 那麼再次請求server時, 就會收到須要登陸的返回值

6.當用戶主動退出系統的時候, 也要在server中刪除redis的key

先後端分離的項目,如何解決登陸問題 - 劉元濤的我的頁面 - 開源中國

相關文章
相關標籤/搜索