角fullstack应用在角fullstack结构不保存用户会话

角fullstack应用在角fullstack结构不保存用户会话

本文介绍了与角fullstack应用在角fullstack结构不保存用户会话护照Facebook的整合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我从这里产生的角fullstack应用程序 -

我使用的是相同的目录结构角fullstack。

现在我试图与Facebook SDK来验证用户身份,做下面的步骤 -

1)指定护照Facebook登录策略

  //创建的auth / Facebook的/ index.js使用严格的;VAR前preSS =要求('前preSS');
VAR护照=要求('护照');
VAR AUTH =要求('../ auth.service');VAR路由器=前press.Router();路由器
  获得('/',passport.authenticate(的Facebook',{
    范围:['邮件','public_profile','user_friends','user_events'],
    failureRedirect:'/',
    会议:假的
  }))  获得('/回调',passport.authenticate(的Facebook',{
    failureRedirect:'/',
    会议:假的
  }),auth.setTokenCookie);module.exports =路由器;//创建的auth / Facebook的/ passport.jsVAR护照=要求('护照');
VAR FacebookStrategy =要求('护照Facebook的)战略。
无功配置=要求('../../配置/环境);
VAR JWT =要求('jsonwebtoken');
exports.setup =功能(用户配置){
  passport.use(新FacebookStrategy({
      clientID的:config.facebook.clientID,
      clientSecret:config.facebook.clientSecret,
      callbackURL:config.facebook.callbackURL
    },
    功能(的accessToken,refreshToken,型材,完成){
      User.findOne({'facebookId':profile.id},功能(ERR,用户){
        如果(ERR)回做(ERR);
        如果(用户){
          返回完成(NULL,用户);
        }其他{
          变种NEWUSER = {};
          NEWUSER ['facebookId'] = profile.id;
          NEWUSER ['providerData'] = {
            名称:Facebook的,
            用户名:profile.username,
            显示名:profile.displayName,
            性别:profile.gender,
            profileUrl:profile.profileUrl
          };
          NEWUSER ['名'] = profile.name.givenName? profile.name.givenName:'';
          NEWUSER [电子邮件] = profile.emails.length大于0? profile.emails [0] .value的:做(的电子邮件没有找到');
          功能generatePassword(){
            变种长度= 8,
              字符集=abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
              retVal的=;
            对于(VAR I = 0,N = charset.length; I<长度; ++ I){
              retVal的+ = charset.charAt(Math.floor(的Math.random()* N));
            }
            返回retVal的;
          }          NEWUSER ['密码'] = generatePassword();
          NEWUSER ['角色'] ='用户';
          VAR用户=新用户(NEWUSER);
          user.save(函数(ERR,用户){
            如果(ERR){执行console.log(ERR); DONE(ERR); }
            VAR令牌= jwt.sign({_ ID:user._id},config.secrets.session,{expiresInMinutes:60 * 5});
            res.json({令牌:令牌});
          });
        }
      });
    }
  ));
};//为Facebook模块认证/ index.js添加的条目

使用严格;

  VAR前preSS =要求('前preSS');
VAR护照=要求('护照');
无功配置=要求('../配置/环境);
VAR用户=要求('../ API /用户/ user.model');//护照配置
要求('./本地/护照')设置(用户,配置)。
要求('./的Facebook /护照')设置(用户,配置)。VAR路由器=前press.Router();router.use('/本地,要求('./本地'));
router.use('/ Facebook的,需要('./ Facebook的'));module.exports =路由器;

在客户端的我做了以下修改 -

  //从安装使用https://github.com/GoDisco/ngFacebook鲍尔安装NG-的Facebook NG-的Facebook
//在角应用模块添加ngFacebook

//中的app.config设置应用程序ID -
$ facebookProvider.setAppId('XXXXXXXXXXXX');

然后添加这一点 - 在app.run

  app.run(函数($ rootScope,$位置,验证){    (函数(D,S,id)的{
      变种JS,FJS = d.getElementsByTagName(多个)[0];
      如果(d.getElementById(ID)){
        返回;
      }
      JS = d.createElement(S);
      js.id = ID;
      js.src =//connect.facebook.net/en_US/sdk.js;
      fjs.parentNode.insertBefore(JS,FJS);
    }(文件,脚本,Facebook的jssdk'));    //如果重定向路由需要身份验证登录,你没有登录
    $ rootScope。在$('$ stateChangeStart',函数(事件,旁边){
      Auth.isLoggedInAsync(功能(的loggedIn){
        如果(next.authenticate&安培;&安培;!的loggedIn){
          $ location.path('/门​​禁/登入');
        }
      });
    });
  })

于是最后调用 / auth /中的Facebook 从我的客户现在我在,我能够将其保存在数据库中的用户登录后获得来自Facebook的数据,但主页总是被重定向到登录状态,而不是仪表盘。

我有以下HTTP拦截在我的客户端应用程序 -

  app.factory('authInterceptor',函数($ rootScope,$ Q $的CookieStore){
    返回{
        //授权令牌添加到页眉
        要求:功能(配置){
            config.headers = config.headers || {};
            如果($ cookieStore.get('令牌')){
                config.headers.Authorization ='承载'+ $ cookieStore.get('令牌');
            }
            返回配置;
        },        //拦截401S和重定向您登录
        responseError:功能(响应){
            如果(response.status === 401){
                $ cookieStore.remove('令牌');
                返回$ q.reject(响应);
            }
            否则,如果(response.status === 403){
                $ cookieStore.remove('令牌');
                返回$ q.reject(响应);
            }否则如果(response.status === 405){
                $ cookieStore.remove('令牌');
                返回$ q.reject(响应);
            }
            其他{
                返回$ q.reject(响应);
            }
        }
    };
})

现在经过我和我的facebook账号,密码,当我收到来自Facebook的回调。这是越来越重定向到相同的登录状态,即使再当API / API /用户/我是给我登录的信息在我的浏览器控制台 -

<$p$p><$c$c>{\"_id\":\"569bc8d6b0c2e8315539539e\",\"facebookId\":\"XXXXX\",\"name\":\"Harshit\",\"email\":\"XXXX\",\"__v\":0,\"providerData\":{\"name\":\"facebook\"},\"messages\":[],\"notifications\":[],\"subjects\":[],\"date\":\"2016-01-17T17:01:10.000Z\",\"role\":[\"user\"]}

所以,我想护照未正确设置授权头或没有比被重定向我到登录页面,我的HTTP拦截其他事只有

我如何调试这个问题,或找出我错了,还是失去了一些东西?


解决方案

在我看来我preFER只是检查服务器是否仍然有你的sesssion信息。

在你的路由,你可以做检查

 时,('/ URL',{
templateUrl:部分,
控制器:控制器,
解析:{的loggedIn:checkLoggedin}})。

只要创建你的函数checkLoggedin这样

\r
\r

VAR checkLoggedin =功能($ Q $ HTTP,$位置){\r
    变种推迟= $ q.defer();\r
\r
    $ http.get('/的loggedIn'),然后(功能(响应){\r
      deferred.resolve();\r
    },函数(响应){\r
      deferred.reject();\r
      $ location.path('/家);\r
    });\r
\r
    返回deferred.promise;\r
  }

\r

\r
\r

基本上你在这里做一个承诺。你说这里到后端,检查我将等待后端送我回一个响应。如果响应是200让它们在网页或其他重新定向到家庭。

您的后端应返回401(取消授权)或200(成功)响应让您的前端知道是否允许页面上的用户。

\r
\r

功能(REQ,RES){\r
\r
  如果(req.isAuthenticated()==真){\r
    res.status(200)。发送(验证);\r
  }其他{\r
    res.status(401)。发送(无法验证);\r
  }\r
\r
}

\r

\r
\r

您可以查看这里的决心更多信息



的决心将在加载你的看法之前运行传递给它的所有依赖关系。

这将让你做出一个HTTP请求到你的后端和护照检查,看看如果会话仍然存在。

角具有使一个http请求到后端每次以确保用户在确实记录

I have an angular-fullstack app generated from here -

https://github.com/angular-fullstack/generator-angular-fullstack

I am using the same directory structure as angular-fullstack.

Now I am trying to authenticate users with facebook sdk and did the following steps -

1) specify passport facebook login strategy

// created auth/facebook/index.js

'use strict';

var express = require('express');
var passport = require('passport');
var auth = require('../auth.service');

var router = express.Router();

router
  .get('/', passport.authenticate('facebook', {
    scope: ['email', 'public_profile', 'user_friends', 'user_events'],
    failureRedirect: '/',
    session: false
  }))

  .get('/callback', passport.authenticate('facebook', {
    failureRedirect: '/',
    session: false
  }), auth.setTokenCookie);

module.exports = router;



// created auth/facebook/passport.js

var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
var config = require('../../config/environment');
var jwt = require('jsonwebtoken');


exports.setup = function (User, config) {
  passport.use(new FacebookStrategy({
      clientID: config.facebook.clientID,
      clientSecret: config.facebook.clientSecret,
      callbackURL: config.facebook.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
      User.findOne({'facebookId':profile.id}, function(err, user){
        if(err) return done(err);
        if(user) {
          return done(null, user);
        } else {
          var newUser = {};
          newUser['facebookId'] = profile.id;
          newUser['providerData'] = {
            name: 'facebook',
            username: profile.username,
            displayName: profile.displayName,
            gender: profile.gender,
            profileUrl: profile.profileUrl
          };
          newUser['name'] = profile.name.givenName ? profile.name.givenName: '';
          newUser['email'] = profile.emails.length>0? profile.emails[0].value : done('email not found');
          function generatePassword() {
            var length = 8,
              charset = "abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
              retVal = "";
            for (var i = 0, n = charset.length; i < length; ++i) {
              retVal += charset.charAt(Math.floor(Math.random() * n));
            }
            return retVal;
          }

          newUser['password'] = generatePassword();
          newUser['role'] = 'user';
          var user = new User(newUser);
          user.save(function (err, user) {
            if (err) { console.log(err); done(err); }
            var token = jwt.sign({_id: user._id }, config.secrets.session, { expiresInMinutes: 60 * 5 });
            res.json({ token: token });
          });
        }
      });
    }
  ));
};

// added entry in auth/index.js  for facebook module

'use strict';

var express = require('express');
var passport = require('passport');
var config = require('../config/environment');
var User = require('../api/user/user.model');

// Passport Configuration
require('./local/passport').setup(User, config);
require('./facebook/passport').setup(User, config);

var router = express.Router();

router.use('/local', require('./local'));
router.use('/facebook', require('./facebook'));

module.exports = router;

In client side I made the following changes -

// installed ng-facebook from https://github.com/GoDisco/ngFacebook using bower install ng-facebook
// added ngFacebook in Angular App module

// set App Id in app.config -$facebookProvider.setAppId('XXXXXXXXXXXX');

Then added this - in app.run

app.run(function ($rootScope, $location, Auth) {

    (function (d, s, id) {
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) {
        return;
      }
      js = d.createElement(s);
      js.id = id;
      js.src = "//connect.facebook.net/en_US/sdk.js";
      fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));

    // Redirect to login if route requires auth and you're not logged in
    $rootScope.$on('$stateChangeStart', function (event, next) {
      Auth.isLoggedInAsync(function (loggedIn) {
        if (next.authenticate && !loggedIn) {
          $location.path('/access/signin');
        }
      });
    });
  })

Then finally calling /auth/facebook from my client now I am getting the data from facebook after a user logs in and I am able to save it in Database, but the homepage always gets redirected to login state and not the dashboard.

I have the following http interceptors in my client app -

app.factory('authInterceptor', function ($rootScope, $q, $cookieStore) {
    return {
        // Add authorization token to headers
        request: function (config) {
            config.headers = config.headers || {};
            if ($cookieStore.get('token')) {
                config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
            }
            return config;
        },

        // Intercept 401s and redirect you to login
        responseError: function (response) {
            if (response.status === 401) {
                $cookieStore.remove('token');
                return $q.reject(response);
            }
            else if (response.status === 403) {
                $cookieStore.remove('token');
                return $q.reject(response);
            } else if (response.status === 405) {
                $cookieStore.remove('token');
                return $q.reject(response);
            }
            else {
                return $q.reject(response);
            }
        }
    };
})

Now after I login with my facebook account, when I receive the callback from facebook. It is getting redirected to the same login state again even when the API /api/users/me is giving me the logged in information in my browser console -

{"_id":"569bc8d6b0c2e8315539539e","facebookId":"XXXXX","name":"Harshit","email":"XXXX","__v":0,"providerData":{"name":"facebook"},"messages":[],"notifications":[],"subjects":[],"date":"2016-01-17T17:01:10.000Z","role":["user"]}

So, I am thinking passport is not setting the authorization headers properly or there is something other than my http interceptor that is redirecting me to the login page only

How can I debug this issue or find out where I am going wrong, or missing something ?

解决方案

In my opinion I prefer just checking whether the server still has your sesssion information.

In your routing you can do check

when('/url', {
templateUrl: 'partial',
controller: 'controller',
resolve: { loggedin: checkLoggedin}}).

Just create your function checkLoggedin like this

  var checkLoggedin = function($q, $http, $location){
    var deferred = $q.defer();

    $http.get('/loggedin').then(function(response){
      deferred.resolve();
    },function(response){
      deferred.reject();
      $location.path('/home');
    });

    return deferred.promise;
  }

Basically your making a promise here. Your saying here go to the backend and check I will wait for the backend to send me back a response. If the response is 200 let them on the page or else redirect to home.

Your back-end should return a 401 (unauthorize) or 200 (success) response letting your front-end know whether to let the user on the page.

function(req,res){

  if (req.isAuthenticated() == true) {
    res.status(200).send("Authenticate.");
  }else{
    res.status(401).send("Not Authenticate");
  }

}

You can check more info about resolve here

The resolve will run all dependencies that is passed to it before loading your view.

This will allow you to make a http request to your back end and verify with passport to see if the session is still there.

Angular has to make a http request to the backend everytime to make sure that the user is indeed logged in.

这篇关于与角fullstack应用在角fullstack结构不保存用户会话护照Facebook的整合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 23:28