未分类

Node.js集成CAS单点登录

思路

  • Java集成cas,官网提供了cas-client.jar
  • Node集成cas,也可以使用相似的npm
  • java官方提供了jar,但js官方没提供
  • npm里有不少人写了第三方的包,但需要筛选
  • 如果可以,也可以自己实现,相当于自己实现cas-client.jar

cas-server服务端直接用官网的代码,java实现。
这里Node实现客户端。

流程

本客户端首次登录流程

  1. 访问cas客户端 http://130.51.23.12:3000/
    • nodejs实现session,校验session是否有票据,发现没有票据
    • session记录当前访问的url
    • 生成需要cas服务端登录成功后回跳的url
    • 跳转到cas服务端
  2. 跳转cas服务端 http://130.51.23.12:8180/cas/login?service=http://130.51.23.12:3000/cas/validate
  3. 回跳客户端 http://130.51.23.12:3000/cas/validate?ticket=ST-43-w5h0klwPzERtNIJJlsuX-cas01.example.org
    • client通过/cas/validate路由到相应处理组件
    • 获取票据
    • 比较票据与session中的票据是否一致
    • 发现不一致
    • 生成校验url,调用cas服务端校验
  4. 校验票据 http://130.51.23.12:8180/cas/serviceValidate?service=http://130.51.23.12:3000/cas/validate&ticket=ST-43-w5h0klwPzERtNIJJlsuX-cas01.example.org
    • 如果服务端返回成功,把ticket复制到session中
    • 获取最初记录的url
    • 跳转
  5. 校验成功跳回 http://130.51.23.12:3000/
    • 重复第一步的校验,此时session有票据,校验成功

本客户端首次登录但其他客户端已登录流程

  • 整个流程与本客户端首次登录类似
  • 不同的是第二步,不再需要通过界面登录,而是cas-server内部直接跳转到第三步
  • 对于客户端的实现来说,流程与[本客户端首次登录]完全一样
  1. 省略
  2. 跳转cas服务端 http://130.51.23.12:8180/cas/login?service=http://130.51.23.12:3000/cas/validate
    • cas服务端发现已登录
    • 不再通过cas服务端界面进行登录,直接登录成功回跳
    • 服务端生成票据,回跳http://130.51.23.12:3000/cas/validate

      这个步骤由cas-server已实现。

  3. 省略…

本客户端非首次登录流程

  1. 访问 http://130.51.23.12:3000/
    • session有票据,直接路由到相应页面

      注意:此时停掉cas-server没有影响,也能访问

登录注册

  • 登录时需要注册到cas服务端,这样别的客户端登出时,服务端也会自动对此客户端登出。

登出

  • 实现logout,相对简单一点。

第三方包

调用代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
const express = require('express');
const ConnectCas = require('connect-cas2');
const bodyParser = require('body-parser');
const session = require('express-session');
const cookieParser = require('cookie-parser');
const MemoryStore = require('session-memory-store')(session);

const app = express();

app.use(cookieParser());
app.use(session({
name: 'NSESSIONID',
secret: 'Hello I am a long long long secret',
store: new MemoryStore() // or other session store
}));

const casClient = new ConnectCas({
//debug: true,
ignore: [
/\/ignore/
],
match: [],
servicePrefix: 'http://130.51.23.165:3000',
//servicePrefix: 'http://localhost:3000',
serverPath: 'http://130.51.23.165:8180',
paths: {
validate: '/cas/validate',
serviceValidate: '/cas/serviceValidate',
proxy: '',
login: '/cas/login',
logout: '/cas/logout',
proxyCallback: ''
},
redirect: false,
gateway: false,
renew: false,
slo: true,
cache: {
enable: false,
ttl: 5 * 60 * 1000,
filter: []
},
fromAjax: {
header: 'x-client-ajax',
status: 418
}
});

app.use(casClient.core());

// NOTICE: If you want to enable single sign logout, you must use casClient middleware before bodyParser.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.get('/logout', casClient.logout());

// or do some logic yourself
app.get('/logout', function (req, res, next) {
// Do whatever you like here, then call the logout middleware
casClient.logout()(req, res, next);
});

app.get('/', function (req, res) {
if (!req.session.cas.user) {
return next();
}

console.log("login.req.session.cas.user is:")
console.log(req.session.cas.user);

const username = req.session.cas.user;
req.session.loggedIn = true;
req.session.username = username;

return res.send('<p>You are logged in. Your username is ' + req.session.cas.user + '. <a href="/logout">Log Out</a></p>');
});

app.listen(3000);

最后

分享到