Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

认证完之后的重定向问题 #6

Closed
JoeShi opened this issue Apr 28, 2016 · 8 comments
Closed

认证完之后的重定向问题 #6

JoeShi opened this issue Apr 28, 2016 · 8 comments

Comments

@JoeShi
Copy link

JoeShi commented Apr 28, 2016

我有一个url http://127.0.0.1:3000/event/:id, 这个网页下的内容,需要获得微信网页授权。

我的基本思路是,检测当前User是否有授权,没有的话就 GET http://127.0.0.1:3000/event/:id/auth/wechat, 获得授权之后,再重定向到 'http://127.0.0.1:3000/event/:id'。刚开始学web, 不知道思路对不对。

这是我在providers.json里关于微信login的配置。

  "wechat-login": {
    "provider": "wechat",
    "module": "passport-wechat-public",
    "appId": "wxdfsafadsfasfdfa",
    "appSecret": "b79a000339b2fdsfafdsafsfa",
    "callbackURL": "http://127.0.0.1:3000/auth/wechat/callback",
    "callbackPath": "/auth/wechat/callback",
    "authPath": "/auth/wechat",
    "scope": ["snsapi_base"],
    "agent": "wechat",
    "authScheme": "OAuth 2.0",
    "state": "login"
  }

server.js 里面加了这么一段代码

app.get('/event/:id/auth/wechat', passport.authenticate('wechat-login'));

app.get('/event/:id/auth/wechat/callback',
  passport.authenticate('wechat-login', {
    successRedirect: '/event/123',
    failureRedirect: '/login'
  })
);

我在微信Web开发者工具里输入 http://127.0.0.1:3000/event/123/auth/wechat,授权成功之后还是定向到 /account. 请问这个需要怎么写?

@JoeShi JoeShi changed the title 如何对一个path重定向 认证完之后的重定向问题 Apr 28, 2016
@vcwen
Copy link
Owner

vcwen commented Apr 28, 2016

你用loopback-passport-component的话,已经在providers写了ballback URL,loopback会处理callbak,而且calbakURL,/auth/wechat/callback,默认成功就是到/account。你可以在providers.json里设置successRedirect为你想要成功后的跳转。server.js不应该在写authenticate方法了

@JoeShi
Copy link
Author

JoeShi commented Apr 30, 2016

谢谢 @wenwei1202 , 我需要实现动态回调, callbackURL 不是固定的,所以看来我不能写在providers.json里了。我按照 这里的做法模仿写了一个。 每次都会重定向到 /error

passport.use("wechat", new WechatStrategy({
  appId: app.get('wechat').appId,
  appSecret: app.get('wechat').secret,
  state: "state",
  scope: "snsapi_userinfo",
  agent: "wechat"
},
  function (accessToken, refreshToken, profile, done) {
    console.log("profile....");
    console.log(profile);
    var User = app.models.user;
    var UserIdentity = app.models.userIdentity;
    UserIdentity.findOrCreate(
      {
        provider: "wechat",
        externalId: profile.unionid
      },
      {
        provider: "wechat",
        externalId: profile.unionid,
        profile: profile,
        created: new Date(),
        authScheme: "OAuth 2.0"
      },
      function (error, userIdentity, created) {
        if (error) {
          done(error);
          return;
        }
        // Check If the UserIdentity is newly created.
        if (created) {
          User.create({
            created: new Date(),
            username: "wechat." + userIdentity.externalId,
            password: "saltyegg",
            email: userIdentity.externalId+"@loopback.wechat.com"
          }, function (error, user) {
            console.log('creating user.........');
            if (!error) {
              userIdentity.updateAttributes(
                {
                  userId: user.id
                }, function (error, instance) {
                  if (error) {
                    console.error(error);
                    done(error);
                  }
                }
              )
            } else {
              console.error(error);
              done(error);
              return;
            }
            console.log("user created.......");
            console.log(user)
          })
        } else {
          // The UserIdentity already exists.
          console.log("user exists........");
          userIdentity.user(function (error, user) {
            done(error, user);
          });
        }
      }
    )
}));


app.get("/auth/wechat/event/:id", function(req, res, next) {
  passport.authenticate("wechat",
    {
      callbackURL: "/auth/wechat/callback/event/" + req.params.id
    })(req, res, next);
});

app.get("/auth/wechat/callback/event/:id", function (req, res, next) {
  passport.authenticate("wechat", {
    callbackURL: "/auth/wechat/callback/event/" + req.params.id,
    successRedirect: "/event/" + req.params.id,
    failureRedirect: "/error"
  })(req, res, next);
});

@JoeShi
Copy link
Author

JoeShi commented Apr 30, 2016

我有多个网页需要authentication. 我的基本想法是:

/event/:id 如果未登陆就发送到 /auth/wechat/event/:id 进行authentication.
/calendar/:id 发送到 /auth/wechat/calendar/:id 进行authentication.

但是我觉得 authenticate 的方式都应该是一个, 不知道对不对。如:

passport.use("wechat", new WechatStrategy({})  //这里的callbackURL 不写,或者下面可以重写。

app.get("/auth/wechat/event/:id", function(req, res, next) {
  passport.authenticate("wechat",
    {
      callbackURL: "/auth/wechat/callback/event/" + req.params.id
    })(req, res, next);
});

app.get("/auth/wechat/calendar/:id", function(req, res, next) {
  passport.authenticate("wechat",
    {
      callbackURL: "/auth/wechat/callback/calendar/" + req.params.id
    })(req, res, next);
});

@vcwen
Copy link
Owner

vcwen commented Apr 30, 2016

我觉得你需要的是connect-ensure-login这个模块, 例如auth path是/auth/wechat, callbck path是/auth/wechat/callback, success redirect是/auth/wechat/account,
app.get("/calendar/:id",ensureLoggedIn('/auth/wechat'),function(req, res) {...})
app.get("/event/:id",ensureLoggedIn('/auth/wechat'),function(req, res) {...})

app.get("/auth/wechat/account",function(req, res) {
if(req.session.returnTo) {
  req.redirect(req.session.returnTo)
} else {
//default handler
}

})

@JoeShi
Copy link
Author

JoeShi commented May 5, 2016

你好 @wenwei1202

代码实现如下, 每次运行会,会被定向到 /account, 但是会报错,

TypeError: Cannot read property 'returnTo' of undefined
    at /Users/Joe/Developer/Wechat/server/server.js:79:26
passport.use("wechat",new WechatStrategy({
    appId: app.get('wechat').appId,
    appSecret: app.get('wechat').secret,
    callbackURL: "/auth/wechat/callback",
    state: "state",
    scope: "snsapi_base",
    agent: "wechat"
  },
  function(accessToken, refreshToken, profile, done) {
    done(null, profile);
  }
));

app.get('/auth/wechat',
  passport.authenticate('wechat'));

app.get('/auth/wechat/callback',
  passport.authenticate('wechat', { failureRedirect: '/login', successReturnToOrRedirect: '/account'}));

app.get('/account', function(req, res) {
  console.log('/account');
  console.log(req.session.returnTo);
  if (req.session.returnTo) {
    res.redirect(req.session.returnTo);
  }
});

app.get('/event/:id', ensureLoggedIn('/auth/wechat'), function(req, res) {
  res.redirect('/event/' + req.params.id);
});

@vcwen
Copy link
Owner

vcwen commented May 5, 2016

TypeError: Cannot read property 'returnTo' of undefined, 说明session没有设置,你有设置session吗?

@JoeShi
Copy link
Author

JoeShi commented May 5, 2016

如果我加上下面这段代码,那么当我 GET /event/123 的时候,就出现无限去请求微信授权的情况,但是我 'GET /auth/wechat' 正常。

代码是模仿 loopback-passport-example写的。

app.middleware('session:before', loopback.cookieParser(app.get('cookieSecret')));
app.middleware('session', loopback.session({
  secret: 'kitty',
  saveUninitialized: true,
  resave: false
}));

@vcwen
Copy link
Owner

vcwen commented May 8, 2016

app.get('/event/:id', ensureLoggedIn('/auth/wechat'), function(req, res) {
res.redirect('/event/' + req.params.id);
});

这个本身就是个死循环

@vcwen vcwen closed this as completed May 8, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants