Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save chengkangzai/8807790a2360bb2d3614792cdd263ac8 to your computer and use it in GitHub Desktop.
Save chengkangzai/8807790a2360bb2d3614792cdd263ac8 to your computer and use it in GitHub Desktop.
Authenticating with APU's CAS
var User = require('../models/user');
var jwt = require('jsonwebtoken');
var config = require('../config/config');
var request = require('request-promise-native');
generateToken = user => {
return jwt.sign(
{ id: user.id, username: user.username },
config.jwtSecret,
{
expiresIn: 86400
}
);
};
getServiceTicket = (tgtUrl, serviceUrl) => {
var options = {
method: 'POST',
uri: tgtUrl,
form: { service: serviceUrl }
};
return request(options);
};
getUserProfile = response => {
const tgtUrl = response.headers['location'];
const serviceUrl = 'https://api.apiit.edu.my';
return getServiceTicket(tgtUrl, serviceUrl).then(function(st) {
var options = {
method: 'GET',
uri: 'https://cas.apiit.edu.my/cas/p3/serviceValidate',
qs: {
service: serviceUrl,
ticket: st,
format: 'json'
}
};
return request(options);
});
};
exports.loginUser = (req, res) => {
if (!req.body.username || !req.body.password) {
return res
.status(400)
.json({ msg: 'Username and password is required.' });
}
var options = {
method: 'POST',
uri: 'https://cas.apiit.edu.my/cas/v1/tickets',
form: {
username: req.body.username,
password: req.body.password
},
resolveWithFullResponse: true
};
// Flow:
// Login to this service -> [ Pass credentials to CAS (TGT retrieved) -> Apply for ST with TGT -> Get user profile with ST ] -> Update db accordingly
//
// http://kb.sites.apiit.edu.my/knowledge-base/api-user-authentication-using-cas/
var tgtService = request(options);
tgtService
.then(getUserProfile)
.then(function(profileRaw) {
const _tgtUrl = tgtService.response.headers['location'];
const _username = req.body.username;
const profile = JSON.parse(profileRaw).serviceResponse
.authenticationSuccess.attributes;
// Mongoose cmd
const query = { username: _username };
const user = {
username: _username,
tgtUrl: _tgtUrl,
displayName: profile.displayName[0],
distinguishedName: profile.distinguishedName.join(), // Following APspace to have .join()
email: profile.userPrincipalName[0]
};
const options = { upsert: true, new: true };
// Update user's profile if user exists, otherwise create a new one
User.findOneAndUpdate(query, user, options, function(err, userDoc) {
if (err) {
return res.status(400).json({
msg: err.message
});
}
// Login successful and profile retrieved, all passed!
return res.status(200).json({
token: generateToken(userDoc)
});
});
})
.catch(function(error) {
var statusCode = error.statusCode | 500; // Throw 500 if server received unexpected errors
return res.status(statusCode).send(JSON.parse(error.error));
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment