1. 程式人生 > >轉: api服務端介面安全性解析

轉: api服務端介面安全性解析

針對
--->非開放性平臺
--->公司內部產品
 
介面特點彙總:
1、因為是非開放性的,所以所有的介面都是封閉的,只對公司內部的產品有效;
2、因為是非開放性的,所以OAuth那套協議是行不通的,因為沒有中間使用者的授權過程;
3、有點介面需要使用者登入才能訪問;
4、有點介面不需要使用者登入就可訪問;
 
針對以上特點,移動端與服務端的通訊就需要2把鑰匙,即2個token。
第一個token是針對介面的(api_token);
第二個token是針對使用者的(user_token);
 
先說第一個token(api_token)
 
它的職責是保持介面訪問的隱蔽性和有效性,保證介面只能給自家人用,怎麼做到?參考思路如下:
按伺服器端和客戶端都擁有的共同屬性生成一個隨機串,客戶端生成這個串,伺服器也按同樣演算法生成一個串,用來校驗客戶端的串。
現在的介面基本是mvc模式,URL基本是restful風格,URL大體格式如下:
http://blog.snsgou.com/模組名/控制器名/方法名?引數名1=引數值1&引數名2=引數值2&引數名3=引數值3
 
介面token生成規則參考如下:
api_token = md5 ('模組名' + '控制器名' + '方法名' + '2013-12-18' + '加密金鑰') = 770fed4ca2aabd20ae9a5dd774711de2
其中的 
1、 '2013-12-18' 為當天時間,
2、'加密金鑰' 為私有的加密金鑰,手機端需要在服務端註冊一個“介面使用者”賬號後,系統會分配一個賬號及密碼,資料表設計參考如下:
欄位名 欄位型別 註釋
client_id varchar(20) 客戶端ID
client_secret varchar(20) 客戶端(加密)金鑰
(注:只列出了核心欄位,其它的再擴充套件吧!!!)

再說第二個token(user_token)
 
它的職責是保護使用者的使用者名稱及密碼多次提交,以防密碼洩露。
如果介面需要使用者登入,其訪問流程如下:
1、使用者提交“使用者名稱”和“密碼”,實現登入(條件允許,這一步最好走https);
2、登入成功後,服務端返回一個 user_token,生成規則參考如下:
user_token = md5('使用者的uid' + 'Unix時間戳') = etye0fgkgk4ca2aabd20ae9a5dd77471fgf
服務端用資料表維護user_token的狀態,表設計如下:
欄位名 欄位型別 註釋
user_id int 使用者ID
user_token varchar(36) 使用者token
expire_time int 過期時間(Unix時間戳)
(注:只列出了核心欄位,其它的再擴充套件吧!!!)
服務端生成 user_token 後,返回給客戶端(自己儲存),客戶端每次介面請求時,如果介面需要使用者登入才能訪問,則需要把 user_id 與 user_token 傳回給服務端,服務端接受到這2個引數後,需要做以下幾步:
1、檢測 api_token的有效性;
2、刪除過期的 user_token 表記錄;
3、根據 user_id,user_token 獲取表記錄,如果表記錄不存在,直接返回錯誤,如果記錄存在,則進行下一步;
4、更新 user_token 的過期時間(延期,保證其有效期內連續操作不掉線);
5、返回介面資料;
 
介面用例如下:
 
1、釋出日誌
URL:  http://blog.snsgou.com/blog/Index/addBlog?client_id=wt3734wy636dhd3636sr5858t6&api_token=880fed4ca2aabd20ae9a5dd774711de2&user_token=etye0fgkgk4ca2aabd20ae9a5dd77471fgf&user_id=12
請求方式:  POST
POST引數:title=我是標題&content=我是內容
返回資料:
{
      'code' => 1, // 1:成功 0:失敗
      'msg' => '操作成功' // 登入失敗、無權訪問
      'data' => []
}

對於 api_token 的校驗,其安全性還可再增強:

增強地方一:

再增加2張表,一個介面表,一個授權表,設計參考如下:

介面表

欄位名 欄位型別 註釋
api_id int 介面ID
api_name varchar(120) 介面名,以"/"作為分割線,如 blog/Index/addBlog
api_domain varchar(256) 所屬領域
is_enabled tinyint(1) 是否可用  1:可用 0:不可用
add_time int 新增時間(戳)

(注:只列出了核心欄位,其它的再擴充套件吧!!!)

授權表

欄位名 欄位型別 註釋
client_id int 客戶端ID
api_id int api編號
api_name varchar(120) 介面名,以"/"作為分割線,如 blog/Index/addBlog
is_enabled tinyint(1) 是否可用  1:可用 0:不可用
add_time int 新增時間(戳)
expire_time int 過期時間(戳)

(注:只列出了核心欄位,其它的再擴充套件吧!!!)

執行過程如下:

1、移動端與服務端生成的 api_token 進行對比,如果不相等,則直接返回錯誤,否則,進入下一步;

2、根據介面URL,組裝 api_name,再加上客戶端傳回的 client_id 為引數,查詢 “授權表”記錄,如果記錄存在,且有效(是否可用,是否過期),則表示許可權驗證通過,返回介面資料,否則返回錯誤資訊;

增強地方二:

對於一些很特殊的介面,怎麼特殊,哪些算特殊,我也不知道,總而言之,就是感覺http請求有可能被劫取,傳遞引數有可能被竄改等情況,還是舉個例子來說吧:

有個直接轉賬介面,頁面上 我輸入的是5元,表示我要給對方某某轉賬5元,結果在http傳遞過程中,被人劫取並竄改成了 10000元,而且入賬物件改成了“黑客”的賬號,那不是虧大發了,思考了一下,應該有2種方案解決這個問題,

方案一:走https,這個就不多說,比較公認的安全機制;

方案二:走數字簽名,實現原理如下:

一個http請求,假如需要傳遞如下3個引數

引數名1=引數值1

引數名2=引數值2

引數名3=引數值3

我們可以再追加一個引數,該引數的名為 identity_key (名字是什麼不重要),該引數的值為 加密金鑰')

服務端接到引數後,再按相同的加密規則重新生成一份 identity_key,服務端的identity_key和客戶端的identity_key 進行校對,如果不相等,表示被竄改過,接下來怎麼操作,自己看著辦吧!

相關推薦

api服務介面安全性解析

針對 --->非開放性平臺 --->公司內部產品   介面特點彙總: 1、因為是非開放性的,所以所有的介面都是封閉的,只對公司內部的產品有效; 2、因為是非開放性的,所以OAuth那套協議是行不通的,因為沒有中間使用者的授權過程; 3、有點介面需要使用者登入才能訪

高效能服務程式設計知識點梳理圖解

轉自:http://www.cppblog.com/changshoumeng/archive/2014/05/09/206871.html posted on 2014-05-19 17:06 胡滿超 閱讀(228) 評論(0)  編輯 收藏 引用 所屬分類: 高效能伺服器

【規範建議】服務介面返回欄位型別與iOS解析

一、本文件的寫作目的   App需要跟產品、UI、後臺、伺服器、測試打交道,app的產出是其他端人員產出的綜合體現。與其他端人員溝通就像是開發寫介面,也就是面向介面程式設計的思想。   本文件講解針對的是服務端返回資料時使用的欄位資料型別如何選擇、iOS端將JSON資料轉模型的時候用什麼型別來定義對應的屬

Java資料介面編寫簡單例子,Java Json解析服務介面輸出Json資料,客戶通過HTTP獲取介面Json資料

實現效果 實現原因 目前主流的CS結構,資料都是通過RESTful風格介面形式呈現,不管是桌面級應用程式還是手機端,介面是我們獲取資料的大多數選擇,主流資料介面呈現形式主要是Json和Xml,後者目前基本漸行漸遠。Json的輕量級和可讀型成為了大多數公司及個人

2016HTML5移動最新兼容問題解決方案;

並不是 按鈕 關鍵字 initial button 手機開發 div off spin 1、安卓瀏覽器看背景圖片,有些設備會模糊。用同等比例的圖片在PC機上很清楚,但是手機上很模糊,原因是什麽呢?經過研究,是devicePixelRatio作怪,因為手機分辨率太小,如果按照

Spring Cloud官方文檔中文版-服務發現Eureka服務

show hub script trying 不同 clu ask local code 官方文檔地址為:http://cloud.spring.io/spring-cloud-static/Dalston.SR3/#spring-cloud-eureka-server 文

HttpClient請求服務介面資料Get與Post請求

public static void main(String[] args) { //String url = "http://10.3.1.32/proxy_services/MDMConsumerProxyService"; String url = "http

通用JS工具類封裝——網路資料請求功能、獲取服務介面 url、引數功能

程式碼片段 'use strict'; var conf = { serverHost = '' }; var _mm = { //網路請求功能 request : function(param){ var _this = this;

阿里App支付服務介面開發(含後臺非同步回撥,退款)

1.引入相關包檔案 maven匯入方式: <dependency> <groupId>com.alipay</groupId> <artifactId>sdk-java</artifactId> <version>

教程node服務阿里雲配製0到完成

前言:有許多前端朋友些完自己的node程式碼,不知道如何放到伺服器上,在此做一下解釋說明如何配置;其實這個伺服器就是好比自己的電腦一樣, 只不過是把桌面等熟悉的檢視介面工具給簡化了,只有電腦的碟符資料夾等,所有的操作都在一個小黑視窗遠端操作該服務端的檔案等服務端配置。 首先不要對它的操作使用的方式嚇到,完

C# http服務介面,通用資料庫介面、與普通字串型別介面

1、通用資料庫介面,返回型別為dt 2、字串型別介面,傳入關鍵字引數,返回型別為字串 [ServiceContract] public interface IDataBaseService { #region 通用資料庫訪問介面 [

http傳輸json進行北京賽車平臺開發服務介面與客戶對接,以及restful實現

北京賽車平臺開發 教程地址:haozbbs.com Q1446595067 話不多說,直接貼程式碼,照寫就好了服務端介面編寫,我用的是springmvc,服務端介面其實和平時web開發一樣,就是返回出json就好了,還有就是接受資料也是json,方法如下:    @Control

從Web後(Java)到遊戲服務的感受

九零後的男生幾乎都是玩電子遊戲長大的,做遊戲開發幾乎是每個九零後男生從小就有的夢想吧。我的大學時代,正好與移動Web高速發展的時代重合了,大學裡幾乎所有同學都是做Web方向的開發,Web前端,Java後

Spring Cloud微服務解決方案①Eureka服務的構建

Eureka是Netflix開發的服務發現框架,本身是一個基於REST的服務,以實現SpringCloud的服務發現功能。包含兩個元件:Eureka Server和Eureka Client。 Eureka Server提供服務註冊服務,各個節點啟動後,會在Eureka Server中

Spring Boot + Spring Cloud 構建微服務系統(七)API服務閘道器(Zuul)

技術背景 前面我們通過Ribbon或Feign實現了微服務之間的呼叫和負載均衡,那我們的各種微服務又要如何提供給外部應用呼叫呢。 當然,因為是REST API介面,外部客戶端直接呼叫各個微服務是沒有問題的,但出於種種原因,這並不是一個好的選擇。 讓客戶端直接與各個微服務通訊,會有以下幾個問題: 客戶端會多次

Android模擬服務介面之moco

在學習Android的過程中,學到網路相關的東西時,沒有服務端介面很是困擾,但是對服務端的知識還不是很瞭解,所以用了moco.jar來模擬服務端介面。 我主要講一下我的專案中用到的介面形式吧。具體的一些教程可以參考這篇文章=>https://blog.csdn.net/sanjay_f/a

axis客戶接收不同引數型別

axis只支援簡單型別的返回值。在這裡逐一介紹axis的各種返回值接受。 1:axis接受基本型別,如int ,string等 引入的系統檔案: import javax.xml.namespace.QName; import javax.xml.rpc.Paramet

.net core api服務跨域配置

第1步:新增包引用(.net core 2.2 已自帶此包,可跳過此步驟) Install-Package Microsoft.AspNetCore.Cors   第2步:在Startup.cs檔案的ConfigureServices方法下增加如下程式碼: #region 跨域 &

死磕Netty原始碼之服務啟動原始碼解析

前言 本部落格講述的是Netty是如何繫結埠、啟動服務。啟動服務的過程中你將會了解到Netty各大核心元件 服務端啟動DEMO 先從一個簡單的服務端啟動DEMO開始,以下是一個標準的Netyy服務端程式碼 public final class

二. Mysql讀寫分離 springboot服務AbstractRoutingDataSource整合

一 DataSourceConfig.class /** * 資料來源配置類 */ @Configuration @EnableTransactionManagement public class DataSourceConfig { /** * 只寫資料來源