App开放接口api安全性—Token签名sign的设计与实现

前言

在app开放接口api的设计中,避免不了的就是安全性问题,因为大多数接口涉及到用户的个人信息以及一些敏感的数据,所以对这些 接口需要进行身份的认证,那么这就需要用户提供一些信息,比如用户名密码等,但是为了安全起见让用户暴露的明文密码次数越少越好,我们一般在web项目 中,大多数采用保存的session中,然后在存一份到cookie中,来保持用户的回话有效性。但是在app提供的开放接口中,后端服务器在用户登录后 如何去验证和维护用户的登陆有效性呢,以下是参考项目中设计的解决方案,其原理和大多数开放接口安全验证一样,如淘宝的开放接口token验证,微信开发 平台token验证都是同理。

签名设计

对于敏感的api接口,需使用https协议

https是在http超文本传输协议加入SSL层,它在网络间通信是加密的,所以需要加密证书。

https协议需要ca证书,一般需要交费。

签名的设计

原理:用户登录后向服务器提供用户认证信息(如账户和密码),服务器认证完后给客户端返回一个Token令牌,用户再次获取信息时,带上此令牌,如果令牌正取,则返回数据。对于获取Token信息后,访问用户相关接口,客户端请求的url需要带上如下参数:

时间戳:timestamp

Token令牌:token

然后将所有用户请求的参数按照字母排序(包括timestamp,token),然后更具MD5加密(可以加点盐),全部大写,生成sign签名,这就是 所说的url签名算法。然后登陆后每次调用用户信息时,带上sign,timestamp,token参数。

例如:原请求https://www.andy.cn/api/user/update/info.shtml?city=北京 (post和get都一样,对所有参数排序加密)

加上时间戳和token

https://www.andy.cn/api/user/update/info.shtml?city=北京×tamp=12445323134&token=wefkfjdskfjewfjkjfdfnc
然后更具url参数生成sign

最终的请求如

https://www.andy.cn /api/user/update/info.shtml?city=北京×tamp=12445323134& token=wefkfjdskfjewfjkjfdfnc&sign=FDK2434JKJFD334FDF2
其最终的原理是减小明文的暴露次数;保证数据安全的访问。

具体实现如下:

1. api请求客户端想服务器端一次发送用用户认证信息(用户名和密码),服务器端请求到改请求后,验证用户信息是否正确。

如果正确:则返回一个唯一不重复的字符串(一般为UUID),然后在Redis(任意缓存服务器)中维护Token----Uid的用户信息关系,以便其他api对token的校验。

如果错误:则返回错误码。

2.服务器设计一个url请求拦截规则

(1)判断是否包含timestamptokensign参数,如果不含有返回错误码。

(2)判断服务器接到请求的时间和参数中的时间戳是否相差很长一段时间(时间自定义如半个小时),如果超过则说明该 url已经过期(如果url被盗,他改变了时间戳,但是会导致sign签名不相等)。

(3)判断token是否有效,根据请求过来的token,查询redis缓存中的uid,如果获取不到这说明该token已过期

(4)根据用户请求的url参数,服务器端按照同样的规则生成sign签名,对比签名看是否相等,相等则放行。(自然url签名 也无法100%保证其安全,也可以通过公钥AES对数据和url加密,但这样如果无法确保公钥丢失,所以签名只是很大程 度上保证安全)。

(5)此url拦截只需对获取身份认证的url放行(如登陆url),剩余所有的url都需拦截。

3.Token和Uid关系维护

对于用户登录我们需要创建token--uid的关系,用户退出时需要需删除token--uid的关系。

签名实现

获取全部请求参数

String sign = request.getParameter("sign");
        Enumeration<?> pNames =  request.getParameterNames();
        Map<String, Object> params = new HashMap<String, Object>();
        while (pNames.hasMoreElements()) {
            String pName = (String) pNames.nextElement();
            if("sign".equals(pName))continue;
            Object pValue = request.getParameter(pName);
            params.put(pName, pValue);
        }

生成签名

public static String createSign(Map<String, String> params, boolean encode)
            throws UnsupportedEncodingException {
        Set<String> keysSet = params.keySet();
        Object[] keys = keysSet.toArray();
        Arrays.sort(keys);
        StringBuffer temp = new StringBuffer();
        boolean first = true;
        for (Object key : keys) {
            if (first) {
                first = false;
            } else {
                temp.append("&");
            }
            temp.append(key).append("=");
            Object value = params.get(key);
            String valueString = "";
            if (null != value) {
                valueString = String.valueOf(value);
            }
            if (encode) {
                temp.append(URLEncoder.encode(valueString, "UTF-8"));
            } else {
                temp.append(valueString);
            }
        }

        return MD5Utils.getMD5(temp.toString()).toUpperCase();
    }

转载 http://www.lai18.com/content/944366.html

http://www.cnblogs.com/whcghost/p/5657594.html

 

传统身份验证方法

Cookie验证是一种比较传统的HTTP安全策略。Cookie验证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端的浏览器端创建了一个Cookie对象;通过客户端带上来Cookie对象来与服务器端的Session对象匹配来实现状态管理的。
默认的,当我们关闭浏览器的时候,cookie会被删除。但可以通过修改cookie 的过期时间使Cookie在一定时间内有效。

基于 Token 的身份验证方法

使用基于Token的身份验证方法,在服务端不需要存储用户的登录记录。基本流程如下:

(1)客户端使用用户名密码请求登录;

(2)服务端收到请求,验证用户名与密码。验证成功服务端签发一个Token,再把这个Token发送给客户端;

(3)客户端每次向服务端发起请求,都需要带着服务端最新签发的Token;

(4)服务端收到请求,验证请求里面的Token,如果验证成功返回请求的数据。流程图如下:


Token身份验证的优势

(1)支持跨域访问:Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输;
(2)更适用CDN:可以通过内容分发网络请求你服务端的所有资料,而你的服务端只要提供API即可;
(3)去耦:不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可;
(4)更适用于移动应用:如果客户端是一个原生平台(比如 iOS,Android,Windows 8 等),是不支持Cookie的,需要额外通过Cookie容器进行处理,这时采用Token验证机制就会简单得多。

 

时间: 2024-12-01 04:34:14

App开放接口api安全性—Token签名sign的设计与实现的相关文章

Uber更新API,提供新功能向第三方APP开放

[TechWeb报道]3月18日消息,Uber对其打车平台API进行更新,提供了一项名为"Request endpoints"的新功能,并面向第三方App开放了API. 首先把按需用车功能整合进11款合作App中,分别是Expensify.Hinge.Hyatt Hotels & Resorts.Momento.OpenTable.Starbucks.Tempo.Time Out.TripAdvisor.TripCase和United Airlines. 对用户而言,他们无需离

新浪微博api 调用-怎么调用新浪微博API开放接口发图片微博

问题描述 怎么调用新浪微博API开放接口发图片微博 我的代码如下,发文字的可以,发图片微博却不行,怎么总是返回400,求解答,他要求图片需要传入binary类型 string url = "https://upload.api.weibo.com/2/statuses/upload.json"; string usernamePassword = UserName + ":" + PassWord; string t_news = string.Format(&qu

电影 影院 影片 信息-电影 APP 基础数据接口 API

问题描述 电影 APP 基础数据接口 API 目前公司想做一个电影APP,与影院的交易接口API有了.但是他们没有基础数据的API (影院详细信息.影片详细信息),他们交易就只有影院.影片的编码+名称交易. 想咨询网上的大牛,怎么获取这些影院.影片的详细基础信息,还有即将上映的电影信息.其他电影购买平台都是怎么做这些基础数据的? 解决方案 1.如果API里没有,看数据库里是否有,如果有的话,可以从数据库中抓取 2.从网上找相关的信息,手工录入系统中

mybatis-手机app后台接口用java怎么写?

问题描述 手机app后台接口用java怎么写? 有没有demo可以提供的?听说用rest.rest不是有get.put吗?那样不是不安全吗? 解决方案 restful api之上你可以附加一些参数,比如appkey,secretid,sign等,伪造的程序因为对不上这些参数,所以不可以调用. 解决方案二: 可以使用网络协议 或者 对数据接口参数进行签名,后台验证签名通过才可操作 否则直接返回 解决方案三: 后台一般来说是基于网络协议的,如果你想和app进行交互的话可以通过htto请求来进行数据的

http接口开发请求参数签名实用工具类

作用: 在http接口对参数做签名,防止接口被非法调用    package com.yanek.util; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.util.ArrayList; import java

token-各位大神,请问些公开部分API关于Token验证的问题

问题描述 各位大神,请问些公开部分API关于Token验证的问题 是个JavaWeb项目,现在想公开部分API给app端的开发者调用,想在调用API前加个Token验证,但是实现起来有点困惑,请各位大神赐教. 我的问题大概如下: 1.用户登录成功后分配一个Token给他 -Token怎样写?(现在思路是根据URL和请求参数生成,并以Json格式传回给用户) -以怎样的方式分配给用户? -用户的Token打算存在内存还是数据库?用户的Token存在哪里?服务器的Token存在哪里? 2.用户每次使

谷歌收购语音识别开放平台 API.ai,或将其整合在 Allo 中

谷歌收购语音识别开放平台 API.ai,或将其整合在 Allo 中 责任编辑:editor007 作者:亚峰 |  2016-09-20 22:16:13 本文摘自:雷锋网 近日,谷歌宣布收购语音识别和自然语言处理交互接口初创公司 API.ai. API.ai 除了为开发者提供语音识别和 NLP 开放平台工具外,还推出一款拥有 2000 万用户的消费级虚拟助手. 目前谷歌的语音识别和 NLP 技术已较为成熟,而且也有基于语音的虚拟助手应用 Google Assistant 和 Google Ho

微信开放接口 加速第三方O2O

小马哥在内部分享时曾谈到,腾讯自己的O2O业务在公众平台进展缓慢,最好是交由第三方去做比较快.其后,作为O2O的基础,微信地图API真的很快就开放出来.11月18日,腾讯的"微信·公众"合作伙伴大会期间,微信官方宣布,公众平台将开放地图API接口.微信地图API接口将整合腾讯地图定位API.云存储API.云检索API.二维地图API和街景API.微信负责人表示,微信地图接口数据由腾讯地图提供,接入腾讯地图数据后,开发者可以基于公众平台卡发出一整套基于地理位置的解决方案,包括包括录入网点

java servlet手机app访问接口(一)数据加密传输验证_java

前面几篇关于servlet的随笔,算是梳理了servlet的简单使用流程,接下去的文章将主要围绕手机APP访问接口这块出发续写,md5加密传输--->短信验证--->手机推送--->分享--->百度云图---->支付....第三方的业务 ...由于我是新手我也是一边学一边写,不足地方希望谅解. 今天这篇文章主要涉及到 javaservlet传输数据的加密,客户端请求参数的组合,并且会附带上我中途遇到的所有问题以及解决方法.  由于手机访问接口是公布出来的,所以不管用什么语言编