vianvio / FE-Companions

山虽高,我心已决要攀登, 路再难,绊不住我的脚跟; 因为我看到生命之路就在这里。 -- 《天路历程》
447 stars 34 forks source link

20200225 - _frank #16

Open vianvio opened 4 years ago

vianvio commented 4 years ago

问题列表:

  1. ui组件库的设计思路,如果大部分以通用ui为主,那么可以用几个特殊复杂的组件作为例子,谈一下组件设计思路和场景。
  2. 分析一下常见社区的组件库设计,比如ant-vue,element-ui,也可以拓展到非vue组件库,比如bootstrap。
  3. 描述一下常见的几种登陆做法,包括前后端如何配合。解释一下如何才能做到像微信这样一年不会重新登录,需要考虑安全性问题。
  4. 账号体系如何设计?考虑怎样满足账号开放的需要;融入接入层和api gateway要怎么做。架构图配合描述,最好给出实际例子
fxxqq commented 4 years ago

第一题:

组件设计思路:

命名

组件命名应该与业务无关,而是根据组件实现的功能来进行命名。同时,也应该与业务文件命名区分开来,可以加一些特有的前缀。可以以组件的名称来命名,例如"ant-btn","mint-cell"等。

遵循一定的设计规范

应该适用于公司的绝大部分业务的交互,让开发变得更高效。

state规范

  1. 如果一个state依赖另外一个state,那么这个数据就不是一个state。只需要写一个变换的处理函数,在 Vue 中可以使用计算属性。应尽量减少state状态。
  2. 如果你的 state 是一个数组,而模版最外层是渲染这个数组,那么你需要做的事是把渲染的项作为一个组件,只接受一个单级对象形式的数据,由外部决定这个组件的展示次数。
  3. 如果一个数据是常量,那么这个数据就应该写死或者作为全局配置属性等,不属于 state。
  4. 如果一个数据需要从外部得到,它应该属于 props。
  5. 如果组件和兄弟组件拥有相同的 state,那么这个 state 应该放到更高的层级中,使用 props 传递到两个组件中。

props规范

  1. props要具有足够的拓展性 组件是对一些具有相同业务场景中的代码或者模块抽象出来,但是不乏两种业务场景中相同的组件会有不同的ui样式或功能,所以组件库的 props 定义需要具备足够的可扩展性,而且组件内部完全受控,保持组件具有统一的输入和输出。一个优秀的组件要尽量减少对外部条件的依赖,同时也方便二次开发和拓展。
  2. 扁平化参数 像 HTML 原生元素那样,只接受原始类型(字符串、数值、布尔值和函数)作为属性,避免复杂的对象。当然,数据除外。
    <!-- good -->
    <my-component
    label="hello"
    :actived="true"
    :width="600"
    :on-show="show">
    </my-component>
    <!-- bad -->
    <my-component :config="myConfig"></my-component>

合理的依赖关系

组件之间不能相互依赖,比如一个form表单去掉一个input或者select仍然可以正常运行,不会造成父组件及兄弟组件功能异常。

轻量化

追求短小精悍,避免太多参数和冗余代码,追求无副作用,但是同时也要保证组件的属性和事件足够的给大多数的组件使用。

文档清晰,便于开发者使用

接口设计符合规范和团队习惯,api可以和已知概念保持一致,有已知的那么就用已知的 api支持复杂的业务项目,尽量让别人用起来简单易上手。

fxxqq commented 4 years ago

第三题:

几种常见的登录认证方式

OAuth 认证

微信、微博、qq,github第三方登录 特点:节省时间。提高用户注册率,安全性也高。 考虑到开发的是技术社区,所以第三方首选github登录,github网页授权是授权码模式(authorization code)的 OAuth 授权模式。 点击“github登录”按钮;用户终端将用户引导到github授权页面; 用户同意授权,应用服务器重定向到之前设置好的 redirect_uri (应用服务器所在的地址),并附带上授权码(code); 应用服务器用上一步获取的 授权码(code) 向github授权服务器发送请求,获取 access_token,也就是上面说的令牌; 之后应用服务器用上一步获取的 access_token 去请求微信授权服务器获取用户的基本信息,例如头像、昵称,邮箱等。

Cookie-Session 认证

用户输入用户名、密码或者用短信验证码方式登录系统; 服务端经过验证,将认证信息构造好的数据结构存储到 Redis 中,并将 key 值返回给客户端; 客户端拿到返回的 key,存储到 local storage 或本地数据库; 下次客户端再次请求,把 key 值附加到 header 或者 请求体中; 服务端根据获取的 key,到 Redis 中获取认证信息。

基于JWT的Token认证(未深入研究,就不过多讨论了)

JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案。 JWT 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,省去查询Redis或其他存储过程 特点: 体积小便于传输,不需要在服务端保存相关信息。

如何实现长时间登录

1. 利用Cookie机制实现

可以把sessionID和有效期保存在cookie中,发给前端,前端收到后保存在本地。当访问后端服务把sessionID和有效期作为参数传给后台进行认证。直到sessionID失效,用户都不需要重新登录。 预防crsf攻击 服务器进行csrf防御校验的时候,是拿用户http请求体中的token参数值和cookie中的csrftoken值进行比对。 如果值一样了,才允许执行下一步。 采用HTTP-Only Cookies

2. token方式

用户登录后会生成一个token字符串,token字符串可以保包含用户信息,服务端并对token设置一定的期限。服务端把生成的token字符串传给客户端,客户端保存token字符串,并在接下来的请求中带上这个字符串。相对于在本地token的安全性更高。由于不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。 预防xss攻击 如果你是将用户提交的字符串存储到数据库的话,需要在前端和服务端分别做过滤

fxxqq commented 4 years ago

第四题

账户体系设置:

  1. 保证账号真实,用户信息可证明用户真实存在。(出于成本的考虑,我采取的是验证邮箱的方式,这样既能确认用户真实性,也能个用户建立沟通渠道)
  2. 确保登录账号的唯一性,一个用户信息只能对应一个账户。(避免一个用户第三方一个账户,账号密码又注册一个账户的情况,比如第三方登录会校验用户信息中的邮箱,如果邮箱注册过,就提示用户用该邮箱登录绑定github账号)
  3. 第三方登录后,重新注册,建立个人账号体系。
  4. 通过图形验证码增加机器批量注册登录的难度。

融入接入层和api gateway,这些名词还是第一次接触。

vianvio commented 4 years ago

第三题前半段总结的挺好,jwt可以在多看一些资料补充一下。长时间登陆的部分,搜索关键词refresh token,再补充一下。目前给的两个方案不适合用来做长期登陆。

第四题目前描述的是一个账号模型,不能算作账号体系。账号体系是将账号本身看做一个复杂系统,考虑多个账号间关联,以及对外用户身份唯一标识和开放认证。对应的就需要在各个不同的业务入口做用户态统一处理,具体可以再多查一些资料。名词还不熟悉的话先从了解他们开始吧。