最近在学习用asp.net webapi搭建小程序的后台服务,因为基于小程序端和后台二者的通信,不像OAuth(开放授权),存在第三方应用。所以这个token是双向的,一个是对用户的,一个是对接口的。本来做了一份是用Oauth的,用的是第三种密码策略模式。但是因为不存在第三方应用,所以不用Oauth这种授权标准。

这个Sample是用简单三层做的,书上得来终觉浅,绝知此事要躬行,实践一次就知道wepapi与前端如何通过token认证进行逻辑交互。

搭建项目

  1. 搭建项目这一点不多说,直接新建一个空的,

用AuthorizationFilter筛选器完成授权

 为什么会用MVC里用到的AuthorizationFilter呢,具体其实我当时不知道WebAPI里面能不能用,但因为领导说最好小程序访问进来,有一个统一验证的方法。因为我之前在另一个项目里创建了一个控件器基类,BaseController,用于做登录验证,权限验证,日志记录,以及公共方法。因为用了OnActionExecuting,所以当时想也没有想,直接搜索Web API OnActionExecuting,看到Web API也有Filter的相关资料。最后参考了[Web APi之认证(Authentication)]((https://www.cnblogs.com/CreateMyself/p/4857799.html),从而顺利完成了这个双向token认证逻辑。
首先,在Controllers文件夹里创建AuthFilterAttribute,即自定义Filter特性。这个class里面先重写OnAuthorization方法。 /// <summary>
/// 最先运行的Filter,被用作请求权限校验
/// </summary>
public class AuthFilterAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{}
}

Web APi之认证(Authentication)两种实现方式【二】(十三)

token规则以及解析请求报文头

   OnAuthorization是重写的。那么具体应该写什么呢?当然是进行验证当前的请求是否有授权,是否是 符合要求的请求报文头。
public override void OnAuthorization(HttpActionContext actionContext)
{
//如果用户方位的Action带有AllowAnonymousAttribute,则不进行授权验证
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
{
return;
}
string authParameter = null;
var authValue = actionContext.Request.Headers.Authorization;//actionContext:Action方法请求上下文
if (authValue != null && authValue.Scheme == "BasicAuth")//这里有BasicAuth和参考资产里面的不同,我们没有认定类,这里的BasicAuth就算是我们自定义的token规则。其实主要是我还没有了解认证身份以及了解GenericIdentity。
{
authParameter = authValue.Parameter; //获取请求参数
var authToken = authParameter.Split('|'); //取出参数,参数格式为(当前时间:加密后的token)将其进行分割
Logging.Error(authParameter);
if (authToken.Length < 2)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.NotAcceptable);//参数不完整,返回406不接受
}
else
{ //参数完整,进行验证
if (ValidateToken(authToken[0],authToken[1]))
{
base.OnAuthorization(actionContext);
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.ExpectationFailed);//验证不通过,未满足期望值417
}
} }
else
{
//如果验证不通过,则返回401错误,并且Body中写入错误原因
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, new HttpError("Token 不正确"));
} }

token验证

 //验证token
public bool ValidateToken(string loginTime,string token)
{
bool flag = true;
DateTime checkTime = DateTime.Parse(loginTime); //先验证时间是否过期
DateTime nowtime = DateTime.Now; TimeSpan a = nowtime - checkTime; Logging.Error("a:"+ a.TotalSeconds); if (a.TotalSeconds > 120)//时间过期
{
flag = false;
}
else
{
string checkToken = Utils.GetTokenString(loginTime);
Logging.Error("1:"+checkToken+";2:"+token);
//比较token
if (token.Equals(checkToken, StringComparison.CurrentCultureIgnoreCase))
{
flag = true;
}
else
{
flag = false;
} }
return flag;
}

测试请求授权

  1. 新建一个Contorller,添加一个名为Test的Action进行测试
[HttpGet]
[Authorize]
[Route("Test")]
//public string Test()
public WxResponseResultModel Test()
{
WxResponseResultModel rsEntity = new WxResponseResultModel();
rsEntity.Code = "200";
rsEntity.Message = "这是后台传的测试方法";
//return "这是后台传的测试方法";
return rsEntity;
}
  1. 前端页面请坟,在本机新建html页面进行测试,token使用了MD5加密方式。
 var keyStr = '123456';
var timestamp = getMyFormatDate(new Date(),'yyyy-MM-dd hh:mm:ss');//获取当前时间
console.log("timestamp:" + timestamp);
var token = hexMD5(keyStr + timestamp);
console.log("token:" + token);
var apiServiceBaseUri = "http://localhost:52545/";
$(function () {
var data = {code:"25"};
$.ajax({
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'BasicAuth ' + timestamp+"|"+token);//token规则
},
url: apiServiceBaseUri + 'Login/Test',
type: "GET",
dataType: 'json',
success: function (data) {
alert(data.Message);
//alert(Message);
}
});
});

首先测试没有[Authorize]的时候,因为最先执行的就是AuthorizationFilter,所以毫无悬念会进入OnAuthorization()进行验证。



其次,在Test这个Action添加[Authorize]看看,这里会有一个疑问,明明是应该认证的方法,添加了[Authorize]属性,更加应该进入OnAuthorization()才对,为什么会拒绝认证呢?



这是因为是配置文件中,配置了全局过滤器。

//注册全局Filter
config.Filters.Add(new AuthFilterAttribute());
把[Authorize]换成配置的[AuthFilter]属性,就可以成功访问了。

发布IIS,联合小程序测试

由于小程序对ajax这一块进行了封装,请求统一使用 wx.request请求,使用wx.request加入报文报求的时候,不像ajax这样,写在beforeSend里面。wx.request是写在header里面。token规则在app.js里面做了全局变量调用。

 wx.request({
url: app.globalData.api + 'Login/Test',
method: "GET",
header: {
'Authorization': app.globalData.header,
'content-type': 'application/json',
}, // 设置请求的 header
success: function (res) {
//如果是对象的话,写法为
console.log(res.data.Message);
// console.log(res.data);
},
fail:function(res){
console.log("fail:" + res)
}
});

测试期间出现一个bug,提示如下:

未能找到 CodeDom 提供程序类型“Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf385

解决办法参考:

未能找到 CodeDom 提供程序类型

参考资料:

api token参考资料

api接口token验证

小程序登录逻辑参考资料

ASP.NET WebApi作服务端开发小程序实现微信授权用户登录实例——登录逻辑1

ASP.NET WebApi作服务端开发小程序实现微信授权用户登录实例——登录逻辑2

ASP.NET WebApi作服务端开发小程序实现微信授权用户登录实例——登录逻辑3

本文WebAPI源代码

ASP.NET WebAPI 双向token实现对接小程序登录逻辑的更多相关文章

  1. [转]微信小程序登录逻辑梳理

    本文转自:http://www.jianshu.com/p/d9996cafdb31 官方文档 文档相关地址: 用户登录 获取用户数据 用户数据的签名验证和加解密                   ...

  2. 微信小程序登录逻辑

    wx.getStorage({ key: 'session_id', success: function(res) { //如果本地缓存中有session_id,则说明用户登陆过 console.lo ...

  3. spring mvc+redis实现微信小程序登录

    本文将详细的介绍微信小程序的登录流程以及在ssm框架下如何实现小程序用户登录 登录流程概要 主要的登录流程可以参考官方提供的一张流程图: 1.微信前台页面: 在微信版本更新之后,提高了安全机制,我们需 ...

  4. django-微信小程序登录

    小程序登录逻辑前端通过调用wx.login()获取code, 将code和用户基本信息发送到后端,后端通过request.get向微信服务器发送get请求获取用户openid和session_key, ...

  5. 做一个开源的小程序登录模块组件(token)

    先了解下SSO 对于单点登陆浅显一点的说就是两种,一种web端的基于Cookie.另一种是跨端的基于Token,一般想要做的都优先做Token吧,个人建议,因为后期扩展也方便哦. 小程序也是呢,做成t ...

  6. 微信小程序登录对接Django后端实现JWT方式验证登录

    先上效果图 点击授权按钮后可以显示部分资料和头像,点击修改资料可以修改部分资料. 流程 1.使用微信小程序登录和获取用户信息Api接口 2.把Api获取的用户资料和code发送给django后端 3. ...

  7. 全栈项目|小书架|微信小程序-登录及token鉴权

    小程序登录 之前也写过微信小程序登录的相关文章: 微信小程序~新版授权用户登录例子 微信小程序-携带Token无感知登录的网络请求方案 微信小程序开通云开发并利用云函数获取Openid 也可以通过官方 ...

  8. 基于Shiro,JWT实现微信小程序登录完整例子

    小程序官方流程图如下,官方地址 : https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html ...

  9. 小程序登录、微信网页授权(Java版)

    首先呢,“登录”.“授权”.“授权登录”,是一样的意思,不用纠结. 写小程序授权登录的代码前,需要了解清楚openid与unionid的区别,这里再简单介绍一下: 腾讯有个 “微信·开放平台”,只有企 ...

随机推荐

  1. NIO ServerSocketChannel ScoketChannel

    package com.yb.nio; import java.io.IOException; import java.net.InetSocketAddress; import java.net.S ...

  2. 【JAVA WEB教程】jsp环境搭建(eclipse)【详细+图文】

    下载JDK(如果你的系统是64位的,那么就下载64位版本的)   然后安装,点击下一步   再点击下一步   安装成功   下载针对JAVA EE的Eclipse(如果你的系统是64位的,那么就下载6 ...

  3. 页面滚动显示或隐藏元素Headroom.js插件帮助你实现滚动效果

    Headroom.js 是什么? Headroom.js 是一个轻量级.高性能的JS小工具(不依赖任何工具库!),它能在页面滚动时做出响应.此页面顶部的导航条就是一个鲜活的案例,当页面向下滚动时,导航 ...

  4. [TJOI 2018]智力竞赛

    Description 题库链接 给出一张 \(m\) 个点的有向图.问可重最小路径覆盖是否 \(\leq n+1\) .若不,求最多用 \(n+1\) 条路径去覆盖,最大化未覆盖点点权最小值. \( ...

  5. 单机多实例mysq 8.0l部署安装

    单机多实例mysql部署安装 目的需求 在单台虚拟机部署部署多实例mysql,用于配置mysql replication,MHA等. 思路 多实例安装mysql可以参考<源编译MySQL8.0的 ...

  6. IdentityServer4 中文文档 -5- (简介)支持和咨询选项

    IdentityServer4 中文文档 -5- (简介)支持和咨询选项 原文:http://docs.identityserver.io/en/release/intro/support.html ...

  7. MVC架构介绍—查询功能的开发

    select和from语句 注意:select和from可以不设置,默认情况下: select获取映射表的所有字段: from获取实体映射表的表名:如果设置select则必须设置frorm,但是允许仅 ...

  8. [android] 手机卫士手机定位的原理

    手机定位的三种方式:网络定位,基站定位,GPS定位 网络定位,手机连上wifi 2g 3g的时候,手机会有一个ip,误差很大 基站定位,精确度与基站的多少有关,几十米到几公里的误差 GPS定位,至少需 ...

  9. 对Spring中IOC和DI的理解

    前几篇讲了Spring中IOC和DI的用法,本篇应该放到三篇之前,但一直没有想到好的讲解方式,后参考https://blog.csdn.net/luoyepiaoxue2014/article/det ...

  10. Nginx + 阿里云SSL + tomcat 实现https访问代理

    第一步:阿里云申请云盾证书服务 第二步:下载证书 第三步:修改Nginx配置 1. 证书文件214033834890360.pem,包含两段内容,请不要删除任何一段内容. 2. 如果是证书系统创建的C ...