网站 API 的两种方式哪种好? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
tonghuashuai
V2EX    程序员

网站 API 的两种方式哪种好?

  • &nbs;
  •   tonghuashuai
    tonghs 2015-09-02 16:55:00 +08:00 6585 次点击
    这是一个创建于 3694 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    打算做一个网站,因为考虑开发移动客户端,所以关于 api 的方式有下面两种想法,大家给点意见哪种好,或者还有别的更好的方法。

    前提

    网站前后端使用 Ajax + JSON 的方式数据交互,打算用 AngularJS

    想到的两种方式

    1. 网站按正常方式开发,然后为客户端单独开发 REST 接口

    这样的问题是:
    网站既然用 Ajax + JSON 也得写 REST 接口,这样就等于写了两套接口,感觉会有重复的工作

    2. 网站和客户端使用一套接口

    这样好处:
    接口就用一套

    这样的问题:
    主要是用户验证有点没有想明白,正常网站的用户验证( Session Cookie )和客户端的用户验证( access_token ) 不一致,导致接口得处理不同的来源使用不同的验证方式,第一种方式倒是没有这个问题。
    其实这个问题倒是想到一种解决方法,初步想的是把 token 存到本地,不清楚这样是不是最佳实现方式。

    或者还有其他的更好的方法

    关于这方面有没有什么最佳实践,大家给点指导,多谢!

    第 1 条附言    2015-09-02 17:47:58 +08:00

    貌似大家更倾向于第二种方法:全部用一套接口。

    那么我有几个问题:
    1. token 存在什么地方合适呢? Cookie ? LocalStorage ?还是 SessionStorage ?仅仅是一个 token 的话,我更倾向于存在 Cookie 中,如果涉及到记住密码什么的是不是就得存到 LocalStorage 中了。大家怎么做的?
    2. 每次请求一个 API 的时候, token 是添加到 HEADER 中还是当一个参数呢,那种更好? 我想了下貌似没什么区别。
    3. 应该会发生跨域的问题吧,假如 API 用子域名的话比如: http://api.test.com/user ,这时在 http://www.test.com/user 页面访问的时候就会有跨域问题吧,怎么破?用 jsonp ?那样就都是 get 方法了,怎么破?

    29 条回复    2015-09-17 20:32:33 +08:00
    hging
        1
    hging  
       2015-09-02 17:04:30 +08:00
    网页也可以用 token 校验. 并没有什么区别.
    neoblackcap
        2
    neoblackcap  
       2015-09-02 17:05:47 +08:00
    其实就是验证问题,我觉得就一套挺好的。

    验证的话,开两个不同的接口不就可以了吗?一套是(session cookie ),一套是(access_token )。
    ljbha007
        3
    ljbha007  
       2015-09-02 17:11:21 +08:00
    都用 session 也没什么不好 access_token 只是在集成 OAuth 的时候需要改的代码比较少
    但是两者实际上完全是一回事
    lerry
        4
    lerry  
       2015-09-02 17:19:16 +08:00 via iPhone
    我看 rails 是支持多种方式验证的, token , cookie 都可以。
    如果是 python 微框架,估计要自己处理一下

    我最近做的项目其实就是你说的第二种方案,登录之后,用 js 把 token 写入 cookie ,每次请求的时候带上,简单封装装一下就可以
    jadecoder
        5
    jadecoder  
       2015-09-02 17:42:52 +08:00
    Angular 也用 HTTP Header 里的 Authorization 验证。 App 启动的时候调一行
    $http.defaults.headers.common.Authorization = token;
    后面的 http 请求就自动带上了
    learnshare
        6
    learnshare  
       2015-09-02 17:46:31 +08:00
    第二种, Web 也作为客户端来开发
    tonghuashuai
        7
    tonghuashuai  
    OP
       2015-09-02 17:48:56 +08:00
    @lerry 怎么解决跨域的问题呢?
    learnshare
        8
    learnshare  
       2015-09-02 17:58:43 +08:00
    token 存哪里不重要,在客户端的安全性都一样(容易被看到);
    token 放在 header 里处理起来会方便一些吧;
    跨域参考 google: CORS 。
    lerry
        9
    lerry  
       2015-09-02 20:38:07 +08:00 via iPhone
    @tonghuashuai
    放 header 应该是更合适的做法
    跨域的话,正如 @learnshare 说的,让服务器端返回允许跨域请求的 headers 就好了
    realpg
        10
    realpg  
    PRO
       2015-09-02 21:02:01 +08:00
    我更倾向于用两套 API
    除非你的 web 是全 ajax 的,基础数据都不通过原始 js 操作之前的 HTML 渲染
    核心数据处理的 Model 设计好可良好复用
    前面的针对 web 和 app 的不同逻辑部分应该很少
    deadEgg
        11
    deadEgg  
       2015-09-02 21:36:18 +08:00
    建议方案一,
    web 纯 ajax 的话,首先你也发现了这几个问题
    我觉得还有一个比较严重的问题就是 sign 的问题.
    无 sign 的 url 容易被人爬接口
    dofaith09
        12
    dofaith09  
       2015-09-02 22:25:23 +08:00
    倾向于用两套
    lijinma
        13
    lijinma  
       2015-09-02 23:01:10 +08:00
    我这边用的是一套, Ajax 用的是 http://jwt.io/, App 使用的类似于 OAuth 的 access_token
    poke707
        14
    poke707  
       2015-09-02 23:07:55 +08:00 via Android
    看看 Json Web Tokens 是否合适你
    http://jwt.io/
    zonghua
        15
    zonghua  
       2015-09-02 23:25:21 +08:00
    @learnshare 但是我有点不懂,客户端每次请求只需要数据,而页面需要页面模板,怎么传输页面模板?一次性全部传过去?就相当于一次浏览你的网站全部下载了页面?
    felixzhu
        16
    felixzhu  
       2015-09-02 23:30:49 +08:00   1
    1.token 存到哪里都可以
    2.header 好,统一处理清晰明确
    3.token 的计算其实是域名无关的,然后网页是一个域,客户端是一个域,为啥会跨域
    RoshanWu
        17
    RoshanWu  
       2015-09-02 23:32:43 +08:00
    @zonghua 人家说的是单页应用(SPA )吧
    flowfire
        18
    flowfire  
       2015-09-03 04:18:54 +08:00
    网页可以加一道通过 cookie 获取临时性的 token 。。。
    learnshare
        19
    learnshare  
       2015-09-03 09:35:46 +08:00
    @zonghua 后端只给数据(一般是 JSON ),前端负责渲染模板
    SolidZORO
        20
    SolidZORO  
       2015-09-03 13:06:01 +08:00
    full api 方式供前後台以及客端。看起是一了,但是不同需求 if 巨多。

    老老分,後台西能不用 api 就不用, SPA 看看就行了,坑多。
    zonghua
        21
    zonghua  
       2015-09-03 13:52:44 +08:00
    @learnshare 所以说我问题的关键是怎么逻辑传模板,web 不是客户端,可以都下载下来.现在后端渲染模板并且又是吧模板切块感觉很混乱.
    learnshare
        24
    learnshare  
       2015-09-03 14:55:01 +08:00
    @zonghua 模板以及整个前端相关的文件,都是静态放在 HTTP 服务器中的,跟服务端一点关系都没有。
    zonghua
        25
    zonghua  
       2015-09-03 15:28:27 +08:00
    @learnshare 就是是由前端的代码直接去获取静态目录的模板文件?
    zonghua
        26
    zonghua  
       2015-09-03 15:30:41 +08:00
    @learnshare 不对,我好像弄错了。是 url 直接访问模板,然后前端代码去请求数据填充到模板吗
    learnshare
        27
    learnshare  
       2015-09-03 15:31:37 +08:00
    @zonghua 是的,前端的资源是通过浏览器直接加载的,跟服务端没什么关系。
    table cellpadding="0" cellspacing="0" border="0" width="100%"> nighca
        28
    nighca  
       2015-09-03 17:31:50 +08:00
    建议用一套啊。

    毕竟区别只存在在身份验证上,登陆这种接口可以针对两种情况写不同的逻辑;一般的接口验证方式上的区别就很小,只是 token 的获取方式不一样,可以被封装起来统一处理的。

    至于后边三个问题:

    1. 存在 cookie 中吧
    2. 这个是指客户端吗,带在哪随意吧。网站的话, cookie 反正肯定是在 header 里的
    3. 服务端可以通过设置 response 的 header ( Access-Control-Allow-Origin )允许指定域名的页面跨域请求的
    a1213125967
        29
    a1213125967  
       2015-09-17 20:32:33 +08:00
    mark
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     987 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 18:52 PVG 02:52 LAX 11:52 JFK 14:52
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86