I have the following script:
function OpenIdLogon(e) {
$.post("/Account/OpenIdLogOn/", { token: e }, function (data) {
$("#userNavigation").html(data);
$(".auth_box").hide();
$(".kb_fading").hide();
});
}
This is the action:
public ActionResult OpenIdLogOn(string token)
{
WebClient cli = new WebClient();
string json = cli.DownloadString(new Uri("http://ulogin.ru/token.php?token=" + Request.Params["token"] + "&host=" + Request.Url.Host));
var obj = JObject.Parse(json);
if (obj["error"] == null)
{
var userName = obj["nickname"].Value<string>();
var email = obj["email"].Value<string>();
FormsAuthentication.SetAuthCookie(userName, true);
}
return PartialView("UserNavigation");
}
And, my UserNavigation:
@if (Request.IsAuthenticated)
{
<a href="#" class="username"><span>@Context.User.Identity.Name</span><i class="icon iUser"></i></a>
<ul class="headLine_link">
<li><a href="#">Profile</a></li>
<li>
@Html.ActionLink("Logg Off", "LogOff", "Account", null, new { @class = "exit" })</li>
</ul>
}
else
{
<ul class="headLine_link">
<li><a id="regLink">Register</a></li>
<li><a id="authLink">Log On</a></li>
</ul>
}
The problem in that Request.IsAuthenticated
equals true only after refresh page.
The problem is the following:
At the time of making the request ($.post("/Account/OpenIdLogOn/"...)
the user it not authenticated.
Then in your action method you authenticate the user, but on the Request object that represents the request the user made before you create the Auth cookie, the user was not authenticated. However, as you say on the next request it works since at that time the user has the Authentication cookie when he makes the request.
One solution here can be to create a viewmodel object to send from your controllers action method to your view. This viewModel can have a field called authenticated, and you can set it properly from the action method. Then check this value instead inside your view. I haven't checked this in Visual Studio, but it should be something like this:
Create the viewmodel:
public class LoginViewModel{
public bool Authenticated{ get; set; }
}
Your action method:
public ActionResult OpenIdLogOn(string token)
{
WebClient cli = new WebClient();
string json = cli.DownloadString(new Uri("http://ulogin.ru/token.php?token=" + Request.Params["token"] + "&host=" + Request.Url.Host));
var obj = JObject.Parse(json);
var viewModel = new LoginViewModel{ Authenticated = Request.IsAuthenticated };
if (obj["error"] == null)
{
var userName = obj["nickname"].Value<string>();
var email = obj["email"].Value<string>();
FormsAuthentication.SetAuthCookie(userName, true);
viewModel.Authenticated = true;
}
return PartialView("UserNavigation");
}
And your view
@model LoginViewModel
@if (Model.Authenticated)
{
<a href="#" class="username"><span>@Context.User.Identity.Name</span><i class="icon iUser"></i></a>
<ul class="headLine_link">
<li><a href="#">Profile</a></li>
<li>
@Html.ActionLink("Logg Off", "LogOff", "Account", null, new { @class = "exit" })</li>
</ul>
}
else
{
<ul class="headLine_link">
<li><a id="regLink">Register</a></li>
<li><a id="authLink">Log On</a></li>
</ul>
}
Creating a viewmodel instead of just sending a bool as model is just because I like to always put the data I send to a view inside a viewmodel. Makes it much easier to extend later on, and makes it easier to read inside the view (you can write @if (Model.Authenticated)
instead of @if (Model)
for example)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With