Я довольно новичок в аутентификации на токенах, и у меня есть проблема с тем, как поддерживать состояние входа после входа в систему. Я хочу создать сайт SPA, для которого я использую Knockoutjs для своего внешнего интерфейса и SammyJS для маршрутизации и изменения представлений. После того, как я войду в систему и получаю токен, я храню его в localStorage и устанавливаю имя пользователя в наблюдаемое, которое я показываю.KnockoutJS + WebAPI 2 Аутентификация токена - поддерживать состояние входа в систему до тех пор, пока токен не истечет
Проблема заключается в том, что после закрытия вкладки или браузера и возврата на сайт токен находится в localStorage, но я не могу видеть, что пользователь вошел в систему. Я хочу сохранить состояние входа до тех пор, пока токен истекает. Мой вопрос: что мне делать с токеном из localStorage, когда я вхожу на сайт, чтобы поддерживать состояние входа этого пользователя?
Нужно ли что-то сделать в классе запуска или проверить, существует ли этот пользователь в БД?
Заранее благодарен!
Вот мой код:
StartupAuth.cs
[assembly: OwinStartup(typeof(EventHub.PL.WebUI.Startup))] namespace EventHub.PL.WebUI {
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get;private set; }
public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
public const string TokenEndpointPath = "/api/token";
public static string PublicClientId { get; private set; }
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString(TokenEndpointPath),
Provider = new ApplicationOAuthProvider(PublicClientId),
//AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
//app.UseOAuthBearerTokens(OAuthOptions);
app.UseOAuthAuthorizationServer(OAuthOptions);
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
}
}
AccountController.cs
[HttpPost]
[AllowAnonymous]
[Route("Login")]
public async Task<IHttpActionResult> Login(LoginUser model)
{
var request = HttpContext.Current.Request;
var tokenServiceUrl = request.Url.GetLeftPart(UriPartial.Authority) + request.ApplicationPath + "/api/Token";
using (var client = new HttpClient())
{
var requestParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", model.Email),
new KeyValuePair<string, string>("password", model.Password)
};
var requestParamsFormUrlEncoded = new FormUrlEncodedContent(requestParams);
var tokenServiceResponse = await client.PostAsync(tokenServiceUrl, requestParamsFormUrlEncoded);
var responseString = await tokenServiceResponse.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<TokenResponse>(responseString);
var responseCode = tokenServiceResponse.StatusCode;
if (responseCode == HttpStatusCode.OK)
{
RegisterUser user = userRepository.GetNameById(json.Id);
var data = new
{
status = "success",
json.access_token,
user.Lastname
};
return Json(data);
}
return Json(new { status = "failed" });
}
}
вот KO часть:
var LoginApp = function() {
var instance = this;
instance.mainViewModel = new MainViewModel();
instance.loginViewModel = new LoginViewModel();
instance.loginRepository = new LoginRepository();
instance.loginViewModel.signIn = function() {
$('.loader-header').show();
var postData = {
email: instance.loginViewModel.email(),
password: instance.loginViewModel.password
}
instance.loginRepository.SignIn(SignInSuccess, postData);
};
instance.SignInSuccess = function(response) {
if (response.status === 'success') {
instance.mainViewModel.username(response.Lastname);
instance.mainViewModel.isVisible(true);
var userData = {
token: response.access_token,
username: response.Lastname
};
localStorage.setItem('AuthorizationData', JSON.stringify(userData));
$('.loader-header').hide();
dialog.close();
} else {
$('.loader-header').hide();
}
};
instance.init = function() {
ko.applyBindings(instance.loginViewModel, document.getElementById("signin-form"));
ko.applyBindings(instance.mainViewModel, document.getElementById("main-wrapper"));
}
instance.init();
}
$(document).ready(function() {
var loginApp = LoginApp();
});
UPDATE
вот моя маршрутизация также
var appRoot = root;
(function ($) {
var app = $.sammy('#page', function() {
this.get('#/home', function (context) {
document.title = 'Home - ' + title;
var url = getUrlFromHash(context.path);
loadView(url, new MainViewModel(), MainApp);
//context.load(url).swap();
});
this.get('#/about', function (context) {
var url = getUrlFromHash(context.path);
loadView(url, new AboutViewModel(), AboutApp);
});
this.get('#/manage', function (context) {
var url = getUrlFromHash(context.path);
loadView(url, new AboutViewModel(), AboutApp);
});
});
$(function() {
app.run('#/home');
});
})(jQuery);
function loadView(url, viewModel, callback) {
$.get(url, function (response) {
var $container = $('#page');
//var $view = $('#page').html(response);
$container.html(response);
callback();
});
}
function getUrlFromHash(hash) {
var url = hash.replace('#/', '');
if (url === appRoot)
url = 'home';
return url;
}
Спасибо за ваш ответ, я использую логин из всплывающего окна, которое я отправляю контроллеру, «#/oauth/login» - это маршрут к контроллеру, не так ли? И мне нужно будет сделать эту проверку на «домашнем» маршруте, верно? Это немного неясно. –
Правильно - в первом фрагменте вы отправляете «письмо» и «пароль» на сервер (т. Е. Контроллер API Wep) в запросе POST на «#/oauth/login». Второй фрагмент определяет маршрут, который проверяет, проверен ли пользователь уже. Если это так, то пользователь направляется на нужную страницу (т. Е. «View/profile.template») –
Хорошо, спасибо! Еще одно, первый фрагмент, который я могу использовать при нажатии кнопки для отправки его на контроллер?Поскольку для входа/регистрации я не использую какой-либо URL-адрес, как для других страниц (#/about), это просто всплывающее окно, и на кнопке я отправляю данные на контроллер. Поэтому я не совсем уверен, как использовать этот подход. Что-то вроде того, что я разместил часть маршрутизации веб-сайта, но вместо того, чтобы использовать пост? Заранее спасибо! –