一般对外提供提供REST 服务,由于信息安全的问题, 都要采用签名认证,今天简单说一下在KBMMW 中如何

实现简单的签名服务?

整个签名服务,模仿阿里大鱼的认证方式,大家可以根据实际情况自己修改。

没有太多的解释,直接上马

     [kbmMW_Rest('method:get, path:getwithcheck')]
[kbmMW_Method]
function getwithcheck( [kbmMW_Rest('value: "$p1", required: true')] const p1:string; [kbmMW_Rest('value: "$p2", required: true')] const p2:string; [kbmMW_Rest('value: "$p3", required: true')] const p3:string; [kbmMW_Rest('value: "$AccessKeyId", required: true')] const AccessKeyId:string; [kbmMW_Rest('value: "$Timestamp", required: true')] const Timestamp:string;
[kbmMW_Rest('value: "$Action", required: true')] const Action:string; [kbmMW_Rest('value: "$Signature", required: true')] const Signature:string):string; end; const AppSecret='sdjhidbTdlfdsj133edyeR';
appkey='xaliontestok'; function MakeSign(const AParams: TStringList; const AppSecret: string): string; implementation uses kbmMWExceptions, mainp; {$R *.dfm}
function specialUrlEncode(const sStr:string):string;
begin
// URLEncode后再增加三种字符替换:加号(+)替换成 %20、星号(*)替换成 %2A、%7E 替换回波浪号(~) Result :=TNetEncoding.URL.EncodeForm(sStr);
Result.Replace('+','%20').Replace('*','%2A').Replace('%7E','~');
end; function MakeSign(const AParams: TStringList; const AppSecret: string): string;
var
I: Integer;
sortedQueryString :string;
stringToSign: string;
sSign :string;
outs: TStringList; pn,pv:string; skey:Tbytes;
begin outs:= AParams;
outs.UseLocale:=True;
outs.Sort; // 参数拼接
sortedQueryString:= ''; for I := to outs.Count - do
begin pn:=specialUrlEncode(outs.Names[I]); pv:=specialUrlEncode(outs.Values[outs.Names[I]]); sortedQueryString:= sortedQueryString +pn + '='+ pv+'&'; end;
setlength(sortedQueryString,length(sortedQueryString)-); stringToSign :='GET&%2F&' + specialUrlEncode(sortedQueryString); skey:=THashSHA1.GetHMACAsBytes(Tencoding.UTF8.GetBytes(stringToSign), Tencoding.UTF8.GetBytes(AppSecret+'&')); sSign := TBase64Encoding.Create.EncodeBytesToString(skey);
Result :=specialUrlEncode(sSign); end; function TkbmMWCustomHTTPSmartService1.getwithcheck(const p1, p2, p3,
AccessKeyId, Timestamp, Action, Signature: string): string;
var inputp:Tstringlist; inputsign:string; begin inputp:=Tstringlist.Create; inputp.Values['P1']:=p1;
inputp.Values['P2']:=p2;
inputp.Values['P3']:=p3; inputp.Values['AccessKeyId']:=AccessKeyId;
inputp.Values['Timestamp']:=Timestamp;
inputp.Values['Action']:=Action;
// inputp.Values['Signature']=Signature; inputsign:= MakeSign(inputp,AppSecret); if inputsign<>specialUrlEncode(Signature) then
begin
Result:='{result:{"ok":"error","value":"sign error"}}';
exit;
end; if appkey<>AccessKeyId then
begin
Result:='{result:{"ok":"error","value":"can not find appkey"}}';
exit;
end; Result:='{"result":{"ok":"ok","value":"'+Action+'"}}';; end;

客户端也很简单

function TForm1.SendSMS(const AppKey, AppSecret, ReceiveNumber, FreeSignName,
TemplateCode, TemplateContent: string; var ResultMsg: string): Boolean; function specialUrlEncode(const sStr:string):string;
begin
// URLEncode后再增加三种字符替换:加号(+)替换成 %20、星号(*)替换成 %2A、%7E 替换回波浪号(~) Result :=TNetEncoding.URL.EncodeForm(sStr);
Result.Replace('+','%20').Replace('*','%2A').Replace('%7E','~');
end; function MakeSign(const AParams: TStringList; const AppSecret: string;var sortQueryStringTmp :String): string;
var
I: Integer;
sortedQueryString :string;
stringToSign: string;
sSign :string;
outs: TStringList; pn,pv:string; skey:Tbytes;
begin outs:= AParams;
outs.UseLocale:=True;
outs.Sort; //SortString( AParams,outs); // 参数拼接
sortQueryStringTmp := ''; for I := to outs.Count - do
begin pn:=specialUrlEncode(outs.Names[I]); pv:=specialUrlEncode(outs.Values[outs.Names[I]]); sortQueryStringTmp := sortQueryStringTmp +pn + '='+ pv+'&'; end;
setlength(sortQueryStringTmp,length(sortQueryStringTmp)-);
sortedQueryString:=sortQueryStringTmp; stringToSign :='GET&%2F&' + specialUrlEncode(sortedQueryString); skey:=THashSHA1.GetHMACAsBytes(Tencoding.UTF8.GetBytes(stringToSign), Tencoding.UTF8.GetBytes(AppSecret+'&')); sSign := TBase64Encoding.Create.EncodeBytesToString(skey);
Result :=specialUrlEncode(sSign); end; var
HTTP: TNetHTTPClient;
JO: TJSONObject;
Params: TStringList;
Response: string;
code:TGUID;
sortQueryStringTmp :string;
signature :string;
sURL :string; ResponseStr: TStringStream; begin
Result := False; CreateGUID(code);
HTTP := TNetHTTPClient.Create(nil);
Params := TStringList.Create();
ResponseStr :=TStringStream.Create('', TEncoding.ASCII);//中文用UTF8
try
//;
//
//请求参数中不允许出现以Signature为key的参数。参考代码如下```
//String accessKeyId = “testId”;String accessSecret = “testSecret”;
//java.text.SimpleDateFormat df = new java.text.SimpleDateFormat(“yyyy-MM-dd’T’HH:mm:ss’Z’”);
//df.setTimeZone(new java.util.SimpleTimeZone(0, “GMT”));// 这里一定要设置GMT时区
//
//java.util.Map paras = new java.util.HashMap();
//// 1. 系统参数
//paras.put(“SignatureMethod”, “HMAC-SHA1”);
//paras.put(“SignatureNonce”, java.util.UUID.randomUUID().toString());
//paras.put(“AccessKeyId”, accessKeyId);
//paras.put(“SignatureVersion”, “1.0”);
//paras.put(“Timestamp”, df.format(new java.util.Date()));
//paras.put(“Format”, “XML”);
//
//// 2. 业务API参数
//paras.put(“Action”, “SendSms”);
//paras.put(“Version”, “2017-05-25”);
//paras.put(“RegionId”, “cn-hangzhou”);
//paras.put(“PhoneNumbers”, “15300000001”);
//paras.put(“SignName”, “阿里云短信测试专用”);
//paras.put(“TemplateParam”, “{\”customer\”:\”test\”}”);
//paras.put(“TemplateCode”, “SMS_71390007”);
//paras.put(“OutId”, “123”); Params.Values['P2'] := 'HMAC-SHA1';
Params.Values['P3'] := GUIDToString(code);
Params.Values['AccessKeyId'] := AppKey;
Params.Values['P1'] := '1.0';
// Params.Values['Timestamp'] := FormatDateTime('yyyy-mm-dd hh:mm:ss', now - 1/3);
Params.Values['Timestamp'] := FormatDateTime('yyyy-MM-dd''T''HH:mm:ss''Z''', now-/);
// Params.Values['Format'] := 'JSON';
Params.Values['Action'] := 'SendSms';
// Params.Values['Version'] := '2017-05-25';
// Params.Values['RegionId'] := 'cn-hangzhou';
//Params.Values['PhoneNumbers'] := ReceiveNumber; // Params.Values['SignName'] := FreeSignName; // Params.Values['TemplateParam'] := TemplateContent;
// Params.Values['TemplateCode'] := TemplateCode; signature:=MakeSign(Params,AppSecret,sortQueryStringTmp); sURL := 'http://127.0.0.1/xalionrest/getwithcheck?signature='+signature+'&'+sortQueryStringTmp;
Memo1.Lines.Text :=sURL; try resultmsg:=http.Get(sURL).ContentAsString ; Memo2.Lines.add( resultmsg); except
on E: Exception do
begin
ResultMsg := E.Message;
Exit;
end;
end; finally
HTTP.Free;
Params.Free;
ResponseStr.Free;
end; end;

运行结果,有图有真相

打完收工。

kbmmw 做REST 服务签名认证的一种方式的更多相关文章

  1. api接口签名认证的一种方式

    请求方 try { using (var client = new HttpClient()) { StringContent content = new StringContent(strParam ...

  2. Android Studio签名打包的两种方式

    签名打包的两种方式: 注:给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行.签名就代表着自己的身份(即keystore),多个app可以使用同一个签名. 如 ...

  3. XFire构建服务端Service的两种方式(转)

    XFire构建服务端service的两种方式,一是用xfire构建,二是和spring集成构建. 一,xifre构建,确保把xfire的jar包导入到工程中或classpath. 1,service的 ...

  4. XFire构建服务端Service的两种方式

    1.原声构建: 2.集成spring构建 http://blog.csdn.net/carefree31441/article/details/4000436XFire构建服务端Service的两种方 ...

  5. 在Spring-Boot中实现通用Auth认证的几种方式

    code[class*="language-"], pre[class*="language-"] { background-color: #fdfdfd; - ...

  6. Android: Android Studio签名打包的两种方式(zz)

    注:给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行.签名就代表着自己的身份(即keystore),多个app可以使用同一个签名. 如果不知道签名是啥意思, ...

  7. android studio学习---签名打包的两种方式

    注:给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行.签名就代表着自己的身份(即keystore),多个app可以使用同一个签名. 如果不知道签名是啥意思, ...

  8. EasyDarwin实现RTSP播放动态认证的两种方式:Basic/Digest & Token

    问题描述 目前为了能够方便开发者,我们将EasyDarwin中的RTSP认证过程直接忽略过了,如果要开启认证的方式,我们可以在代码中打开: case kRoutingRequest: { // Inv ...

  9. SpringCloud服务消费有哪几种方式?

    一.使用LoadBalancerClient LoadBalancerClient接口的命名中,可以看出这是一个负载均衡客户端的抽象定义,spring提供了一个实现 org.springframewo ...

随机推荐

  1. iOS上传本地代码到git

    1.顾名思义,首先你得注册一个github账户 这个我就不细说了. 2.然后你得创建一个 repository  步骤见下图 3.相当于创建成功 会跳到下图界面 4.一看就很清楚了 create a ...

  2. java中如何给控件设置颜色

     1. tv.setTextColor(Color.parseColor("#000000"));2. tv.setTextColor(getResources().getCo ...

  3. Linux背背背(3)

    目录 1.文件操作命令 2.文件夹操作命令 文件操作命令 创建 命令:touch 语法:#touch 文件的名字      文件名可以是一个完整的路径 如果后面的参数文件名指定了路径,则表示在指定的路 ...

  4. IDEA查看类继承关系及生成类关系图

    1.在想要查看的类上按 Ctrl + H -> Diagrams -> Show Diagrams -> Java Class Diagrams -> Show Impleme ...

  5. 杂谈1.py

    Python命名规则: 1. 组成:数字/字母/下划线 只能以字母,下划线开头 不能包含空格 避免Python关键字和函数名 简短且具有描述性 描述数据形态及支持操作 Python动态类型 变量无类型 ...

  6. 字符串格式化:f-strings

    字符串格式化一般使用: {}.format 和 %s 那么python 3.6以后新加的一个功能就是: value=“zhang”f“string{value}” # 他的主要功能就是对于我们的f或F ...

  7. VS2015+Opencv3.2配置(一次配好)

    对于 VS2015+QT5.8的配置我就不介绍了,由于我配置的比较早,具体有的东西忘掉了,大家可以参考下面这几篇文章. 留白留白留白留白留白(稍后补) 对于Opencv+VS的配置是我重点要说的内容. ...

  8. springboot maven 部署

    1.在pom.xml文件中配置tomcat插件 <build> <plugins> <plugin> <groupId>org.springframew ...

  9. 详解vue组件的is特性:限制元素&动态组件

    在vue.js组件教程的一开始提及到了is特性 意思就是有些元素,比如 ul 里面只能直接包含 li元素,像这样: <ul> <li></li> </ul&g ...

  10. html转换pdf

    项目需求:移动端APP项目需要在手机上签订合同,将html转换成pdf格式的文件 解决方案:是用插件wkhtmltopdf; 记录用法:1.网址https://wkhtmltopdf.org/ 下载压 ...