完爆Facebook/GraphQL,APIJSON全方位對比解析(二)-權限控制

相關閱讀:前端

完爆Facebook/GraphQL,APIJSON全方位對比解析(一)-基礎功能java

完爆Facebook/GraphQL,APIJSON全方位對比解析(三)-表關聯查詢git

 

自APIJSON發佈以來,不斷有網友拿來和Facebook的GraphQL對比,github

甚至有很多人聲稱「完爆」APIJSON。數據庫

然而事實正好相反,本系列博客將以大量真實依據來證實,json

APIJSON「完爆」GraphQL!後端

 

APIJSON的口號是:

後端接口和文檔自動化,前端(客戶端) 定製返回JSON的數據和結構!api

APIJSON的簡介:

APIJSON是一種爲API而生的JSON網絡傳輸協議。
爲 簡單的增刪改查、複雜的查詢、簡單的事務操做 提供了徹底自動化的API。
能大幅下降開發和溝通成本,簡化開發流程,縮短開發週期。
適合中小型先後端分離的項目,尤爲是互聯網創業項目和企業自用項目。服務器

經過自動化API,前端能夠定製任何數據、任何結構!
大部分HTTP請求後端不再用寫接口了,更不用寫文檔了!
前端不再用和後端溝通接口或文檔問題了!不再會被文檔各類錯誤坑了!
後端不再用爲了兼容舊接口寫新版接口和文檔了!不再會被前端隨時隨地沒完沒了地煩了!網絡

特色功能

在線解析

  • 自動生成文檔,清晰可讀永遠最新
  • 自動生成請求代碼,支持Android和iOS
  • 自動生成JavaBean文件,一鍵下載
  • 自動管理與測試接口用例,一鍵共享
  • 自動校驗與格式化JSON,支持高亮和收展

對於前端

  • 不用再向後端催接口、求文檔
  • 數據和結構徹底定製,要啥有啥
  • 看請求知結果,所求即所得
  • 可一次獲取任何數據、任何結構
  • 能去除重複數據,節省流量提升速度

對於後端

  • 提供通用接口,大部分API不用再寫
  • 自動生成文檔,不用再編寫和維護
  • 自動校驗權限、自動管理版本
  • 開放API無需劃分版本,始終保持兼容
  • 支持增刪改查、模糊搜索、正則匹配、遠程函數等

視頻演示:i.youku.com/apijson

[如下Gif圖看起來比較卡,實際在手機上App運行很流暢] 
  

項目主頁: github.com/TommyLemon/…

 

 

完爆Facebook/GraphQL,APIJSON全方位對比解析(二)-權限控制

 

自動化權限控制(APIJSON特有):

GraphQL【沒有】提供權限控制的功能,甚至在官方文檔和源碼裏連如何實現的教程也幾乎沒有,

而僅僅說起了如何在你的【業務代碼】裏去【手動】實現一個【所屬人】角色的權限控制。

 

 

 

高亮的這行代碼

if (context.user && (context.user.id === post.authorId))
複製代碼

就是在後端手動寫的postType中,手動加的resolve函數裏,加上這麼一個userId關係判斷。

也就只能實現當查詢postType對應的表時,只有post裏的authorId和來訪user的id相等時,才返回查到的結果。

 

下文中善意地提示了你,不要寫死在某個Type的resolver函數中,

而是應該封裝到一個postReponsitory,裏面放一個getBody的函數,內部再實現這個判斷並return。

這樣不只邏輯清晰,還能在別的Type中用到postType時(例如userType嵌套postType)能夠複用。(PS: 這個文檔中沒說,我幫它說了)

 

 

但即使你花了時間去新寫一個類、再新寫一個函數,作了這個封裝,那也只是postType能複用而已,

其它的humanType,droidType,queryType等一大堆Type不都仍是得一個個寫?

https://github.com/graphql/graphql-js/blob/master/src/__tests__/starWarsSchema.js

 

 

並且當今的互聯網應用中,不論是網站,仍是移動端App,稍微複雜一點的都不僅是【所屬人】這麼一個角色,

其中大部分,尤爲是社交應用,都包含 【聯繫人】、【朋友圈】這兩個角色。

固然,全部具備帳戶登陸的應用,均可以分【已登陸】、【未登陸】這兩種角色。

 

既然GraphQL不提供權限控制功能,那就只能本身根據每種角色一個個寫了。

按照以上惟一一個官方示例,咱們對應全部角色的判斷應該是:

未登陸:

if (context.user == null || context.user.id == null || context.user.id <= 0) {
  return post.body;
}

return null;
複製代碼

 

已登陸:

if (context.user && context.user.id && context.user.id > 0) {
  return post.body;
}

return null;
複製代碼

 

朋友圈:

var userId = context.user == null ? null : context.user.id;
var contactIdList = context.user == null ? null : context.user.contactIdList; //聯繫人id列表
if ((userId && userId === post.authorId) || (contactIdList && contactIdList.indexOf(post.authorId) >= 0)) {
  return post.body;
}

return null;
複製代碼

 

聯繫人:

var contactIdList = context.user == null ? null : context.user.contactIdList; //聯繫人id列表
if (contactIdList && contactIdList.indexOf(post.authorId) >= 0) {
  return post.body;
}

return null;
複製代碼

 

所屬人:

if (context.user && (context.user.id === post.authorId)) {
  return post.body;
}

return null;
複製代碼

  

 

僅僅用GraphQL實現查詢postType這一個Type對應的角色權限控制,竟然就要寫這麼多判斷代碼!

假設咱們數據庫有20張表(實際很輕量級的應用才只有這麼少的表),對應寫了20個Type,那就是 20*5 = 100 個判斷!!!

僅僅是判斷角色權限的代碼就至少有 20*(4 + 4 + 6 + 5 + 4) = 460 行!!!

 

 

而APJSON提供了自動化的權限控制,能夠細分到 每張表、每行記錄、每種角色、每種操做 的控制粒度!

並且每張表只須要寫3行代碼就能配置各類角色的增刪改查的權限!

 

咱們用APIJSON來操做一張表,例如用戶表User,代碼寫3行就夠了:

//註冊表並添加權限,用默認配置
@MethodAccess
public class User {
  //內容通常僅供表字段說明及Android App開發使用,服務端不用的可不寫。
}

//DemoVerifier內添加權限
ACCESS_MAP.put(User.class.getSimpleName(), getAccessMap(User.class.getAnnotation(MethodAccess.class)));
複製代碼

或者能夠再定製下POST請求的角色權限:

@MethodAccess(
  POST = {UNKNOWN, ADMIN} //只容許未登陸角色和管理員角色新增User,默認配置是 {LOGIN, ADMIN}
)
public class User {}
複製代碼

  

而後運行下Server工程就能夠請求了:

URL:http://apijson.cn:8080/get

請求:

{
    "User": {
        "id": 82001
    }
}
複製代碼

返回:

{
    "User": {
        "id": 82001,
        "sex": 0,
        "name": "Test",
        "tag": "APIJSON User",
        "head": "http://static.oschina.net/uploads/user/19/39085_50.jpg",
        "contactIdList": [
            82004,
            82021,
            70793
        ],
        "pictureList": [
            "http://common.cnblogs.com/images/icon_weibo_24.png"
        ],
        "date": "2017-02-01 19:21:50.0"
    },
    "code": 200,
    "msg": "success"
}
複製代碼
 複製代碼

咱們再試試APIJSON的自動化權限控制到底 能不能達到指望、會不會被繞過 吧。

 

查詢用戶開放信息User:
/get/{"User":{"id":38710}}

請求成功:

{
    "User": {
        "id": 38710,
        "sex": 0,
        "name": "TommyLemon",
        "tag": "Android&amp;Java",
        "head": "http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000",
        "contactIdList": [
            82003,
            82005,
            90814,
            82004,
            82009,
            82002,
            82044,
            93793,
            70793
        ],
        "pictureList": [
            "http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000",
            "http://common.cnblogs.com/images/icon_weibo_24.png"
        ],
        "date": "2017-02-01 19:21:50.0"
    },
    "code": 200,
    "msg": "success"
}
複製代碼

  

查詢用戶隱私信息Privacy:
/get/{"Privacy":{"id":38710}}

請求失敗,無GET權限:

{
    "Privacy": {
        "id": 38710
    },
    "code": 401,
    "msg": "Privacy 不容許 UNKNOWN 用戶的 GET 請求!"
}
複製代碼

  

看下源碼:

@MethodAccess(
  GET = {},
  GETS = {OWNER, ADMIN}
)
public class Privacy {}
複製代碼

很明顯,get是不容許的,能夠用gets,但也必須是OWNER, ADMIN這2種角色中的一個。

 

URL: http://apijson.cn:8080/gets/
請求:

{
    "Privacy": {
        "id": 38710
    },
    "tag": "Privacy"
}
複製代碼

仍然失敗,由於沒登陸,未登陸是UNKNOWN用戶,這裏自動補全爲OWNER:

{
    "Privacy": {
        "id": 38710
    },
    "tag": "Privacy",
    "code": 407,
    "msg": "未登陸,請登陸後再操做!"
}
複製代碼

 

那咱們能不能僞造一下角色騙過APIJSON呢?試試看:

{
    "Privacy": {
        "id": 38710,
        "@role": "circle"
    },
    "tag": "Privacy"
}
複製代碼

仍是同樣的報錯:未登陸。

{
    "Privacy": {
        "id": 38710,
        "@role": "circle"
    },
    "tag": "Privacy",
    "code": 407,
    "msg": "未登陸,請登陸後再操做!"
}
複製代碼

  

好吧,我登陸後再試,新的報錯:

{
    "Privacy": {
        "id": 38710,
        "@role": "circle"
    },
    "code": 401,
    "msg": "Privacy 不容許 CIRCLE 用戶的 GETS 請求!"
}
複製代碼

爲何呢?角色不符合OWNER, ADMIN這2種角色中的一個。


那換成OWNER角色呢?

{
    "Privacy": {
        "id": 38710,
        "@role": "owner"
    },
    "tag": "Privacy"
}
複製代碼

繼續報錯:

{
    "Privacy": {
        "id": 38710,
        "@role": "owner"
    },
    "code": 401,
    "msg": "id = 38710 的 Privacy 不容許 OWNER 用戶的 GETS 請求!"
}
複製代碼

  

換成後端沒有的角色呢?

{
    "Privacy": {
        "id": 38710,
        "@role": "test"
    },
    "tag": "Privacy"
}
複製代碼

報錯,角色不存在:

{
    "Privacy":  {
        "id": 38710 ,
        "@role": "test"
    },
    "code": 406 ,
    "msg": "角色 test 不存在!只能是[UNKNOWN,LOGIN,CONTACT,CIRCLE,OWNER,ADMIN]中的一種!"
}
複製代碼

 

再試試 "@role": "admin" :

{
    "Privacy": {
        "id": 38710,
        "@role": "admin"
    },
    "tag": "Privacy"
}
複製代碼

仍然報錯:

{
    "Privacy": {
        "id": 38710,
        "@role": "admin"
    },
    "code": 406,
    "msg": "角色設置錯誤!不容許在寫操做Request中傳 Privacy:{ @role:admin } !"
}
複製代碼

管理員角色是隻能在服務器內部設置的,不容許傳哦。

 

因此,按照Privacy的權限配置,前端只有用OWNER角色去查當前已登陸帳戶(id=82001)的Privacy:

{
    "Privacy": {
        "id": 82001,
        "@role": "owner" //Request表中配置了自動補全,可不寫
    },
    "tag": "Privacy"
}
複製代碼

纔會返回正確的結果: 

{
    "Privacy": {
        "id": 82001,
        "certified": 1,
        "phone": 13000082001,
        "balance": 8781.46
    },
    "code": 200,
    "msg": "success"
}
複製代碼

 

注: 以上APIJSON請求均可以在 http://apijson.org 在線工具上測試

 

 

 

總結

GraphQL沒有提供權限控制的功能,須要後端針對每張表對應的Type去對應各類角色一個個手寫大量判斷代碼!

而APJSON提供了自動化的權限控制,能夠細分到 每張表、每行記錄、每種角色、每種操做 的控制粒度!

並且每張表只須要寫3行代碼就能配置各類角色的增刪改查的權限!以上測試用例也說明了它不但配置簡單還很可靠!

 

 

APIJSON,讓後端接口和文檔自動化,前端(客戶端) 定製返回JSON的數據和結構!

創做不易,右上角點Star支持下吧,很是感謝^_^

github.com/TommyLemon/…

相關文章
相關標籤/搜索