angularjs - Using passport on node to authenticate angular JS SPA -
i implementing spa requires local authentication koajs server using passport-local strategy. server looks @ post request, looks user mongodb , authenticates using passport, sending success or failure client. the problem facing when send request angular app, although params , body being correctly parsed , user being found in database, not being authenticated. same post request sent postman authenticated. tried @ request being sent both postman , angular @ sever, , postman has cookie , token in request. maybe that's cause of issue. in case, here code:
angular side relevant code request being sent.
let obj = json.stringify({ username: username, password: password }); $http({ url: 'http://192.168.0.105:3000/login', method: 'post', //headers: { 'authorization' : 'basic secret' }, //headers: { 'content-type': 'application/json' }, data: obj }).then( (response) => { console.log("response") })
some of global configuration have done:
app.config(['$qprovider', '$httpprovider', function($qprovider, $httpprovider) { $qprovider.erroronunhandledrejections(false); $httpprovider.defaults.usexdomain = true; }
the server side code (server.js):
const passport = require('koa-passport') const mongoose = require('mongoose'); const userschema = require('./schema.js') const koa = require('koa') const app = new koa() const bodyparser = require('koa-bodyparser') const router = require('koa-router')() //for login , unprotected links const protectedrouter = require('koa-router')() //for protected links const session = require('koa-session') const sessionkey = 'mysession key'; const cors = require('kcors'); //to enable cors app.use(cors()); app.proxy = true app.keys = ['your-session-secret'] app.use(session({ key: sessionkey }, app)) app.use(bodyparser({})); mongoose.connect("mongodb://username:password@somedatabase.mlab.com:port/databasename"); passport.serializeuser(function (user, done) { done(null, user.id); }); passport.deserializeuser(function (id, done) { userschema.findbyid(id, function (err, user) { done(err, user); }); }); const localstrategy = require('passport-local').strategy passport.use(new localstrategy(function (username, password, done) { console.log(username + " " + password) //to check if data being received server request userschema.findone({ username: username }, function (err, user) { if (err) { console.log("err") return done(err); } if (!user) { console.log("no user exists") return done(null, false, { message: 'unknown user' }); } if (!user.authenticate(password)) { console.log("invalid pwd") return done(null, false, { message: 'invalid password' }); } console.log("done") return done(null, user); } ); })) app.use(passport.initialize()) app.use(passport.session()) router.post('/login', //function (ctx) { console.log (ctx.request.rawbody); console.log(ctx.request.body); console.log(ctx.request)}) passport.authenticate('local', { successredirect: '/success', failureredirect: '/failure', })) failure = async (ctx) => { console.log("failure") ctx.response.body = "failure" } success = async (ctx) => { console.log("success") ctx.response.body = "success"; } app.use(router.routes()); //authenticating middleware app.use(function (ctx, next) { if (ctx.isauthenticated()) { console.log("authenticated") return next() } else { console.log("not authenticated") ctx.redirect('/') } }) protectedrouter.get('/success', success) protectedrouter.get('/failure', failure) app.use(protectedrouter.routes()); // start server const port = process.env.port || 3000 app.listen(port, () => console.log('server listening on', port))
the user schema (schema.js):
var mongoose = require('mongoose'); var userschema = new mongoose.schema({ username: string, password: string, }); userschema.methods.authenticate = function (password) { return this.password === password; }; module.exports = mongoose.model('credentials', userschema);
when use postman, code generated is:
post /login http/1.1 host: localhost:3000 content-type: application/json cache-control: no-cache postman-token: 7265406f-9fad-4761-a2c0-dde64455bc74 {"username": "username", "password": "password"}
this console response on server:
username password done authenticated success
when use angular app, response on console:
username password done not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated not authenticated
for reason middleware not authenticate angular request, if credentials found in request.
to investigate bit more, changed portion of server.js:
router.post('/login', //function (ctx) { console.log (ctx.request.rawbody); console.log(ctx.request.body); console.log(ctx.request)}) passport.authenticate('local', { successredirect: '/success', failureredirect: '/failure', }))
to this:
router.post('/login', function (ctx) { console.log (ctx.request.rawbody); console.log(ctx.request.body); console.log(ctx.request)}) //passport.authenticate('local', { //successredirect: '/success', //failureredirect: '/failure', //}))
in order see if there difference between request generated $http in angular , postman. these changes lead following output on server console request postman:
{"username": "username", "password": "password"} { username: 'username', password: 'password' } { method: 'post', url: '/login', header: { 'cache-control': 'no-cache', 'postman-token': 'f8bfd1ef-f2f3-42b3-8797-74cb9c6aa48b', 'content-type': 'application/json', 'user-agent': 'postmanruntime/6.2.5', accept: '*/*', host: 'localhost:3000', cookie: 'mysession key=eyjwyxnzcg9ydci6eyj1c2vyijointk5mwe1ndzmntm5ytuxyzqwnmy4oddjin0sil9lehbpcmuioje1mdmzodc0ntmwnzgsil9tyxhbz2uiojg2ndawmdawfq==; mysession key.sig=g3peuhhlsqmexh2grncxr0rdrbq', 'accept-encoding': 'gzip, deflate', 'content-length': '58', connection: 'keep-alive' } }
and console output request angular $http:
{"username":"username","password":"password"} { username: 'username', password: 'password' } { method: 'post', url: '/login', header: { host: 'localhost:3000', 'user-agent': 'mozilla/5.0 (windows nt 10.0; wow64; rv:54.0) gecko/20100101 firefox/54.0', accept: 'application/json, text/plain, */*', 'accept-language': 'en-us,en;q=0.5', 'accept-encoding': 'gzip, deflate', referer: 'http://192.168.0.107:8080/', 'content-type': 'application/json', 'content-length': '55', origin: 'http://192.168.0.107:8080', connection: 'keep-alive' } }
there no token or cookie being passed in angular request. reason lack of authentication? (i thought cookie supposed sent server serve maintain persistent sessions)
i tried send post simple html document post form. successful , request had cookie in it.
i have tried using withcredentials option, turn http method options 1 post, didn't work either (i did change the router.post router.options in server.js- upon investigating network activity in browser console, found somehow data object not being included in options request):
$http({ url: 'http://localhost:3000/login', method: 'post', withcredentials: true, headers: { 'content-type': 'application/json' }, data: obj }).then( (response) => { console.log("response")withcredentials : true })
any suggestions?
ps: package.json
{ "name": "server", "version": "1.0.0", "description": "", "main": "server.js", "scripts": { "test": "echo \"error: no test specified\" && exit 1", "start": "node server.js" }, "author": "", "license": "isc", "dependencies": { "kcors": "^2.2.1", "koa": "^2.3.0", "koa-bodyparser": "^4.2.0", "koa-passport": "^3.0.0", "koa-router": "^7.2.1", "koa-session": "^5.5.0", "mongoose": "^4.11.7", "passport-local": "^1.0.0" } }
Comments
Post a Comment