V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tonghuashuai
V2EX  ›  程序员

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

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

    背景

    打算做一个网站,因为考虑开发移动客户端,所以关于 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  
       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 容易被人爬接口
    zyx89513
        12
    zyx89513  
       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 是的,前端的资源是通过浏览器直接加载的,跟服务端没什么关系。
    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   ·   实用小工具   ·   903 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:45 · PVG 05:45 · LAX 13:45 · JFK 16:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.