【问题标题】:Web api - Saving user data throughout the life of the application like SessionWeb api - 在应用程序的整个生命周期中保存用户数据,如 Session
【发布时间】:2019-02-01 02:05:31
【问题描述】:

如何在纯 Web Api 应用中保存用户数据,贯穿 Session 等整个应用生命周期,以便在每次请求时我们都可以使用保存的用户数据。 我看到在WEB API中每个请求都是独立的,与前一个请求没有联系,因此不能使用Session。

谁能帮帮我?

【问题讨论】:

  • 无法维持与 Web API 的会话。因为,它完全是无国籍的。您可以将声明用于令牌。这是为任何 api 调用的任何请求保存用户数据的最佳方式。
  • 令牌如何使用?
  • 你的前端架构是什么?你的 dotnet 版本是多少?
  • 我使用 angular,Dot.Net 框架 4.6.1
  • 有一个例子stackoverflow.com/questions/38661090/…如果你不懂就敲我

标签: c# session asp.net-web-api


【解决方案1】:

您需要从 Nuget 安装 Microsoft.Owin。然后将其添加到您的启动课程中。

public void ConfigureAuth(IAppBuilder app) 
        { 

            var OAuthOptions = new OAuthAuthorizationServerOptions 
            { 
                AllowInsecureHttp = true, 
                TokenEndpointPath = new PathString("/token"), 
                AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(20), 
                Provider = new SimpleAuthorizationServerProvider() 
            }; 

            app.UseOAuthBearerTokens(OAuthOptions); 
            app.UseOAuthAuthorizationServer(OAuthOptions); 
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 

            HttpConfiguration config = new HttpConfiguration(); 
            WebApiConfig.Register(config); 
        } 

        public void Configuration(IAppBuilder app) 
        { 
            ConfigureAuth(app); 
            GlobalConfiguration.Configure(WebApiConfig.Register); 
        }

然后需要添加类似的提供者

[EnableCors(origins: "*", headers: "*", methods: "*")]  
    public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider  
    {  
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)  
        {  
            context.Validated(); //   
        }  

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)  
        {  
            var identity = new ClaimsIdentity(context.Options.AuthenticationType);  
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });  

            using (var db = new TESTEntities())  
            {  
                if (db != null)  
                {  
                    var empl = db.Employees.ToList();  
                    var user = db.Users.ToList();  
                    if (user != null)  
                    {  
                        if (!string.IsNullOrEmpty(user.Where(u => u.UserName == context.UserName && u.Password == context.Password).FirstOrDefault().Name))  
                        {  
                            identity.AddClaim(new Claim("Age", "16"));  

                            var props = new AuthenticationProperties(new Dictionary<string, string>  
                            {  
                                {  
                                    "userdisplayname", context.UserName  
                                },  
                                {  
                                     "role", "admin"  
                                }  
                             });  

                            var ticket = new AuthenticationTicket(identity, props);  
                            context.Validated(ticket);  
                        }  
                        else  
                        {  
                            context.SetError("invalid_grant", "Provided username and password is incorrect");  
                            context.Rejected();  
                        }  
                    }  
                }  
                else  
                {  
                    context.SetError("invalid_grant", "Provided username and password is incorrect");  
                    context.Rejected();  
                }  
                return;  
            }  
        }  
    }

如果需要,您可以添加索赔数量。然后修改你的 WebApiConfig 公共类 WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务

        EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*");  
        config.EnableCors(cors);  

        // Web API routes  
        config.MapHttpAttributeRoutes();  

        config.Routes.MapHttpRoute(  
            name: "DefaultApi",  
            routeTemplate: "api/{controller}/{id}",  
            defaults: new { id = RouteParameter.Optional }  
        );  

        var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();  
        jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();  
    }  
}

然后像一样测试你的令牌

然后您通过授权标头传递您的令牌。然后获取您的索赔。

api 请求示例

获取索赔数据的示例代码

var principal = this.Request.GetRequestContext().Principal as ClaimsPrincipal;
var claims = principal.Claims.ToList();
            var age = claims.FirstOrDefault(c => c.Type == "Age")?.Value;

【讨论】:

    【解决方案2】:

    您可以使用会话变量,例如:

    Session["FirstName"] = FirstNameTextBox.Text;
    Session["LastName"] = LastNameTextBox.Text;
    

    使用会话变量:

    // When retrieving an object from session state, cast it to 
    // the appropriate type.
    ArrayList stockPicks = (ArrayList)Session["StockPicks"];
    
    // Write the modified stock picks list back to session state.
    Session["StockPicks"] = stockPicks;
    

    欲了解更多信息,请访问:MSDN

    【讨论】:

    • 如何在 API 中维护会话?
    • 我已经尝试过了,但是每次请求会话都会更新。这可能不适合 web api 应用程序
    • 会话不能与 Web API 一起使用,因为会话将数据存储到浏览器 cookie 中,它只能在浏览器中工作,但不能用于桌面和移动应用程序。
    • 没有类似的方法吗?
    猜你喜欢
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 2023-02-18
    • 1970-01-01
    • 2011-03-26
    相关资源
    最近更新 更多