dingtalk passport plugin for egg
$ npm i egg-passport egg-passport-dingtalk --save
// {app_root}/config/plugin.js
exports.passport = {
enable: true,
package: 'egg-passport'
}
exports.passportDingtalk = {
enable: true,
package: 'egg-passport-dingtalk',
};
apply the app from https://open-dev.dingtalk.com/#/loginAndShareApp
// {app_root}/config/config.default.js
exports.passportDingtalk = {
key: 'your-key',
secret: 'your-secret',
// default is /callback/dingtalk
callbackURL: '/callback/dingtalk',
// default is /passport/dingtalk
loginURL: '/passport/dingtalk',
oauthPageConfig: {
title: 'your-dingtalk-oauth-page-title',
logo: 'your-app-icon',
slogan: 'your-app-slogan',
},
// Your custom dingtalk oauth page, if this is set, the default oauthPageConfig will be invalid
customLoginURL: '/auth',
};
see config/config.default.js for more detail.
// {app_root}/config/config.default.js
exports.passportDingtalk = {
};
key | value | note |
---|---|---|
key | string | required |
secret | string | required |
callbackURL | string default is '/callback/dingtalk' | optional |
loginURL | string default is '/passport/dingtalk' | optional |
oauthPageConfig.title | string | optional |
oauthPageConfig.logo | string | optional |
oauthPageConfig.slogan | string | optional |
customLoginURL | string | optional If this is set, then you should render the oauth page by yourself |
// app/router.js
module.exports = app => {
app.get('/', 'home.index');
// authenticates routers
app.passport.mount('dingtalk', app.config.passportDingtalk);
// this is a passport router helper, it's equal to the below codes
//
// const dingtalk = app.passport.authenticate('dingtalk');
// app.get('/passport/dingtalk', dingtalk);
// app.get('/passport/dingtalk/callback', dingtalk);
};
Notice: The dingtalk is different with github or twitter, it need to be rendered by yourself. Luckily, we provide a nice default page for you.
Usually, you could write a middleware to handle if a request need to be login, example will like below:
// app/router.js
module.exports = app => {
app.get('/', app.middleware.needLogin(null, app), 'home.index');
};
About how to write a middleware, please refer this
// app/middleware/need-login.js
module.exports = (options, app) => {
return async function needLogin (ctx, next) {
const passportDingtalkConfig = app.config.passportDingtalk;
if (!ctx.isAuthenticated()) {
return ctx.redirect(passportDingtalkConfig.loginURL);
}
await next();
}
}
Then you visit the path '/', it will redirect you to the login page;
// app/router.js
module.exports = app => {
app.get('/', 'home.index');
// authenticates routers
app.passport.mount('dingtalk', app.config.passportDingtalk);
app.passport.verify(async (ctx, user) => {
// find user from database
//
// Authorization Table
// column | desc
// --- | --
// provider | provider name, like github, twitter, facebook, weibo and so on
// uid | provider unique id
// user_id | current application user id
const auth = await ctx.model.Authorization.findOne({
uid: user.id,
provider: user.provider,
});
const existsUser = await ctx.model.User.findOne({ id: auth.user_id });
if (existsUser) {
return existsUser;
}
// call user service to register a new user
const newUser = await ctx.service.user.register(user);
return newUser;
});
};
See https://github.com/eggjs-community/egg-passport#apis.
app.passport.mount(strategy, options)
: Mount the login and the login callback routers to use the givenstrategy
.app.passport.authenticate(strategy, options)
: Create a middleware that will authorize a third-party account using the givenstrategy
name, with optionaloptions
.app.passport.verify(handler)
: Verify authenticated userapp.passport.serializeUser(handler)
: Serialize user before store into sessionapp.passport.deserializeUser(handler)
: Deserialize user after restore from session
ctx.user
: get the current authenticated userctx.isAuthenticated()
: Test if request is authenticated* ctx.login(user[, options])
: Initiate a login session foruser
.ctx.logout()
: Terminate an existing login session
Please open an issue here.