C# 如何在 OAuth 重定向后保留会话或 Cookie 信息?

发布于 2024-12-06 02:37:46 字数 1178 浏览 1 评论 0原文

我让用户使用 Facebook 登录我的网站。他们从我的网站发送到 Facebook,然后在获得网站许可后重定向回来。我面临的问题是访问我在离开站点之前设置的会话变量。当用户返回站点时,将创建一个全新的会话。奇怪的是,如果用户导航该网站,原始会话的某些页面将可以访问,有时新创建的会话也可以访问。 我尝试过创建cookie: Response.Cookies["用户"]["登录"] = "true"; 只要用户没有离开网站,我就可以很好地访问这些 cookie,但是一旦他们离开并回来,我似乎也无法访问这些 cookie。所以我的问题是,在用户被发送离开网站之前以及重定向回来之前保留数据的最佳方法是什么?

AccountController:

public void Login()
{
    Session["BeforeLogin"] = "foo";
    redirect(FacebookUrl);
}

//Where Facebook redirects the user back to
public ActionResult OAuth(string code, string state)
{
    if (LoginSuccessful)
    {
        Session["LoggedIn"] = true;
    }
    return View();
}

HomeController:
    public HomeController()
{
    setLoggedInSession();
}

public void setLoggedInSession()
{
    //This is where I'm having the inconsistency
    string foo = Session["BeforeLogin"];
    ViewData["LoggedIn"] = Session["LoggedIn"];
    //It'll either be BeforeLogin is null and LoggedIn is true
    //or BeforeLogin will be "foo" and LoggedIn will be null
}

编辑: 有关此问题的一些新信息。进行一些测试后,我发现当我仅使用单个实例时,会话似乎工作正常。当我执行高可用性(运行 5 个实例)时,我开始遇到问题。在 IE 中最明显。我的假设是,当您从 Facebook 重定向回该网站时,您将获得一个与离开时不同的实例,并且它会在设法检索原始会话之前创建一个新会话。

I'm having users login to my site using Facebook. They are sent away from my site to Facebook and then redirected back after they have given the site permission. The problem I'm facing is accessing the Session variables I set before they left the site. When the user returns to the site an entirely new Session is created. The strange thing is if the user navigates the site, some pages the original session will be accessible, and sometimes the newly created session.
I've tried creating cookies:
Response.Cookies["user"]["LoggedIn"] = "true";
As long as the user hasn't left the site I'm able to access those cookies fine, but as soon as soon as they leave and come back I don't seem to be able to access those either. So my question is what is the best way to persist data from before before a user is sent away from the site to when then are redirected back?

AccountController:

public void Login()
{
    Session["BeforeLogin"] = "foo";
    redirect(FacebookUrl);
}

//Where Facebook redirects the user back to
public ActionResult OAuth(string code, string state)
{
    if (LoginSuccessful)
    {
        Session["LoggedIn"] = true;
    }
    return View();
}

HomeController:
    public HomeController()
{
    setLoggedInSession();
}

public void setLoggedInSession()
{
    //This is where I'm having the inconsistency
    string foo = Session["BeforeLogin"];
    ViewData["LoggedIn"] = Session["LoggedIn"];
    //It'll either be BeforeLogin is null and LoggedIn is true
    //or BeforeLogin will be "foo" and LoggedIn will be null
}

EDIT:
Some new information about this issue. Doing some testing I've found that the Session seems to work fine when I'm only using a single instance. When I do high availability though (running 5 instances) is when I start experiencing the issues. Most noticeably in IE. My hypothesis is that when you're redirected back to the site from Facebook you're getting a different instance than you left and it creates a new session before it manages retrieves the original one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

两仪 2024-12-13 02:37:46

我的猜测是您正在使用会话状态的默认模式,即 proc 模式中基于 cookie 的模式。

在默认模式下,您所描述的行为是预期的。您正在单个虚拟机的单个进程的内存中设置值,这些值不会神奇地转到另一个虚拟机或进程。由于 Azure 可以自由地将您的请求路由到任何实例,因此您只能靠运气才能获得您设置的相同会话值。实际上,如果您尝试足够长的时间,您应该会看到,即使是单个实例,您的会话值也会随着 VM 重新启动或 IIS 回收您的工作进程而消失。

http://msdn.microsoft.com/en 中有相当多的信息-us/library/ms178586.aspx 会话状态模式。

但我的建议是避免使用会话状态。当您掌握会话时,您将非常熟悉 IIS 管道中的 http 处理,您将不再需要这种抽象。

My guess is you are using the default mode for the session state, which is cookie based in proc mode.

With default mode the behaviour you describe is expected. You are setting values in memory of a single process of a single VM, which will not magically go to another VM or process. And since Azure is free to route your requests to any instance, it is only by luck you can get the same session value you set. Actually if you try long enough you should see that even with a single instance your session values would disappear as VM reboots, or IIS recycles your worker process.

There is quite a bit of informatin in http://msdn.microsoft.com/en-us/library/ms178586.aspx on session state modes.

But my recommendation is avoid using sessions state. By the time you master sessions you would be well familiar with the http processing in IIS pipeline, that you will not need this abstraction anymore.

意犹 2024-12-13 02:37:46

AppFabric缓存:
“跨 Windows Azure AppFabric 和 Windows Server AppFabric 的一致开发模型。
访问控制服务提供的安全访问和授权。”
它对于任何一个实例来说都是非常驻的。

AppFabric Caching:
"Consistent development model across both Windows Azure AppFabric and Windows Server AppFabric.
Secured access and authorization provided by the Access Control service."
It's non-resident to any one instance.

风筝在阴天搁浅。 2024-12-13 02:37:46

如果你想使用持久性 cookie,你需要这样的东西:

Response.Cookies.Add(new HttpCookie("name", "value") { Expires = DateTime.UtcNow + TimeSpan.FromDays(7) });

If you want to use a persistent cookie, you want something like this:

Response.Cookies.Add(new HttpCookie("name", "value") { Expires = DateTime.UtcNow + TimeSpan.FromDays(7) });
洋洋洒洒 2024-12-13 02:37:46

如果 cookie 损坏,您可以通过在回调 URL 中添加查询字符串参数来解决此问题,然后如果存在查询字符串参数,则将其填充回会话数据中。

发送动态查询字符串参数时,Facebook 应用程序回调不会验证失败,并且会像发送时一样将它们传回。

If the cookies are breaking, you could solve this by adding a query string parameter in the callback Url, then stuff it back into your session data if the query string parameter is present.

The Facebook app callback doesn't fail validation when dynamic query string parameters are sent, and passes them back the same as they are sent in.

仅一夜美梦 2024-12-13 02:37:46

问题在于,当 Facebook 进行回调时,请求中没有传递会话 cookie,因此 .Net 创建了一个新的会话 cookie。如果您在运行 fiddler 时进行调试,您应该会看到这一点。

如果要传递变量,请将其放入回调 QueryString 中,或者使用 ajax 发出请求。 社交插件非常适合这种事情。

顺便说一句,希望您知道在会话中存储任何类型的身份验证/授权都是完全不安全的。我认为你的代码只是用于调试,但我想我会提到它。

The trouble is when Facebook makes the callback there is no session cookie passed in the request, so .Net creates a new one. You should see this if you debug whilst running fiddler.

If you want to pass a variable put it in the callback QueryString, or use ajax to make the request. Social Plugins are great for this kind of thing.

Btw hope you are aware storing any kind of authentication/authorisation in session is totally insecure. I think your code is just for debug, but thought I'd mention it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文