我在这里把头撞到了墙上。请帮忙。 我开发了一个MVC 4.0 Web应用程序。 我正在使用Facebook SDK登录该网站。 为了论证,我有2个动作方法:索引和信息。 索引是用户点击"使用Facebook登录"按钮,在他输入凭据后,他应该被重定向到Info动作方法。 (从那里他可以退出)。 这是索引方法:
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
我在web.config中有这个:
<authentication mode="Forms">
<forms loginUrl="~/Home/Index" timeout="2880" />
</authentication>
这些是我在Facebook开发者处为我的应用程序输入的设置:
画布网址:
http://localhost/[AppName]/
安全画布网址:
https://localhost/[AppName]/
网站网址:
http://localhost/[AppName]/
有效的OAuth重定向URI:
http://localhost/
以及
http://localhost/[AppName]/home/index
问题是:
我想让Info操作方法仅供授权用户使用,所以很自然地,我用[Authorized]属性修饰它:
[Authorize]
public ActionResult Info()
{
var client = new FacebookClient();
var oauthResult = client.ParseOAuthCallbackUrl(Request.Url);
// Build the Return URI form the Request Url
var redirectUri = new UriBuilder(Request.Url);
redirectUri.Path = Url.Action("Info", "Home");
// Exchange the code for an access token
dynamic result = client.Get("/oauth/access_token",
new { client_id = AppId,
redirect_uri = redirectUri.Uri.AbsoluteUri,
client_secret = SecId,
code = oauthResult.Code });
// Read the auth values
string accessToken = result.access_token;
Session["access_token"] = accessToken;
DateTime expires = DateTime.UtcNow.AddSeconds(Convert.ToDouble(result.expires));
// Get the user's profile information
dynamic me = client.Get("/me",
new
{
fields = "first_name,last_name,email,picture",
access_token = accessToken
});
var userInfo = new InfoModel()
{
firstName = me.first_name,
lastName = me.last_name,
emailId = me.email,
picture = me.picture,
accessToken = result.access_token
};
return View("Info", userInfo);
}
所以现在我有两个未打开的场景:我可以登录我的应用程序,但登录后,我被重定向到主页/索引,而不是主页/信息。
OR
我可以正常登录(登录后我被重定向到Home / Info,正如预期的那样)但是我也可以直接浏览Info动作方法(因为我必须删除[Authorize]属性才能登录。
它就像一个魔方!
对不起,帖子很长,但我不得不详细说明。
答案 0 :(得分:0)
我找到并回答了。 它涉及一些解决方案,但它同样好:
[AllowAnonymous]
public ActionResult Info()
{
if (Request.Url.AbsoluteUri.Contains("Home/Info?code"))
{
var client = new FacebookClient();
var oauthResult = client.ParseOAuthCallbackUrl(Request.Url);
// Build the Return URI form the Request Url
var redirectUri = new UriBuilder(Request.Url);
redirectUri.Path = Url.Action("Info", "Home");
// Exchange the code for an access token
dynamic result = client.Get("/oauth/access_token",
new
{
client_id = AppId,
redirect_uri = redirectUri.Uri.AbsoluteUri,
client_secret = SecId,
code = oauthResult.Code
});
// Read the auth values
string accessToken = result.access_token;
Session["access_token"] = accessToken;
DateTime expires = DateTime.UtcNow.AddSeconds(Convert.ToDouble(result.expires));
// Get the user's profile information
dynamic me = client.Get("/me",
new
{
fields = "first_name,last_name,email,picture",
access_token = accessToken
});
var userInfo = new InfoModel()
{
firstName = me.first_name,
lastName = me.last_name,
emailId = me.email,
picture = me.picture,
accessToken = result.access_token
};
FormsAuthentication.SetAuthCookie(userInfo.emailId, true);
return View("Info", userInfo);
}
else
return View("Index");
}
正如您所看到的,我在Action方法的开头有一个条件: 如果且仅当网址包含单词&#34; code&#34;然后用户可以进行身份验证,否则,他将被重定向回第一页。 如果单词&#34; code&#34;存在,这意味着用户有一个令牌,因此他已经正确输入了他的凭证,所以现在可以提取他的详细信息。 在提取过程结束时,就在重定向到视图之前,我添加了:
FormsAuthentication.SetAuthCookie(userInfo.emailId, true);
为了保存cookie。这是[Authorize]属性正常运行所需的,否则代码将表现为您未经过身份验证,即使您已经过身份验证。
现在我可以安全地为我希望仅向经过身份验证的用户提供的所有操作方法添加[Authorize]属性。 不要忘记将[AllowAnonymous]属性添加到用作身份验证过程一部分的每个操作方法,否则用户将无法浏览其各自的视图。
顺便说一句, 如果用户试图键入,他将收到错误,因为他仍然需要令牌。