0%

背景

要在App Store 新上架的App要在4月份前适配iOS 13,其中App如果使用了第三方登录的,就要同时支持AppleId 登录,也是一种第三方登录.

先放一个时序图:

第一步,客户端和AppleServer交互后请求后端

客户端向苹果服务器请求,拿到用户的信息和identityToken.主要返回数据如下:

  • user: 用户唯一ID,在一个开发者账号下的APP获取到的是一样的,类似微信开发API中的openid;
  • identityToken: 「JWT」格式的token,用于验证信息合法性。
  • email: 用户邮箱(可能为空)
  • fullName: 昵称等信息
  • realUserStatus: 是否是“真实用户”,可用于反作弊,对抗黑灰产. (0为黑户,1为不确定,2为正常用户)

拿到信息后调用接口,把信息传给后端,但这样有个重要的问题就是不能保证安全性,无法判断请求是否是伪造的。这个时候就要使用identityToken了。

注意:当第一次认证成功之后,将不会再返回email,fullName等信息,可以在设置->Apple ID->密码与安全性->使用您AppleID的App 中删除对应的APP。

第二步,后端校验identityToken合法性

identityTokenString实际上是JWT(JSON Web Token)格式的文件,JWT文件由三部分组成:

  • Header
  • Payload
  • Signature
阅读全文 »

7. 整数反转

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321

阅读全文 »

Docker命令

获取镜像

docker pull [选项] [Docker 仓库地址[:端口号]]仓库名[:标签]

  • []内的属于可选参数,所以最基本的命令就是 docker pull mongo 这样的.
  • Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
  • 仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。

例如: docker pull mongo
这里没有给定Docker仓库地址就用默认的Docker Hub,没有给定标签就拿最新的

1
Using default tag: latest

具体的tag可以去hub.docker.com里查看

列出镜像

docker image ls


列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。

其中仓库名、标签在之前的基础概念章节已经介绍过了。镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个 标签。

阅读全文 »

Node.js EventEmitter

Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。Node.js 里面的许多对象都会分发事件,而这所有这些产生事件的对象都是 events.EventEmitter 的实例.events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装.了解EventEmitter对象可以帮助理解 node是怎么运作的,也可以自己写事件监听和触发.

阅读全文 »

流的基本类型

Node.js,Stream 有四种流类型:

  • Readable - 可读操作。

  • Writable - 可写操作。

  • Duplex - 可读可写操作.

  • Transform - 操作被写入数据,然后读出结果。

所有的 Stream 对象都是 EventEmitter 的实例。

常用的事件有:

  • data - 当有数据可读时触发。

  • end - 没有更多的数据可读时触发。

  • error - 在接收和写入过程中发生错误时触发。

  • finish - 所有数据已被写入到底层系统时触发。

样例

阅读全文 »

一、前言
elementUI有说明文档,但我为什么还要重新写一下呢?因为文档也有坑,一开始使用时你复制进去,可能都没有效果。也不知道原因在哪,就如Backtop回到顶部的组件,不去看源码,真心不知道是怎么个所以然。一开始,我把这个组件放到我页面的底部,结果是无效果的,而且还会报css的这两个样式错误(.page-component__scroll .el-scrollbar__wrap),看完这个文档,也没找到这两个是什么东西,在哪设置。全文搜索,也没找到这两个css。最后逼我进去看Backtop组件源码,看懂后,删除了没必要的东西,放置的位置调整一下,完美解决。这也是本站使用的回到顶部的效果。以下我会贴出官方文档及源码,还有解决思路

二、官方文档 https://element.eleme.cn/#/zh-CN/component/backtop

Backtop 回到顶部
返回页面顶部的操作按钮

基础用法
滑动页面即可看到右下方的按钮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
Scroll down to see the bottom-right button.
<el-backtop target=".page-component__scroll .el-scrollbar__wrap"></el-backtop>
</template>

自定义显示内容
显示区域被固定为 40px * 40px 的区域, 其中的内容可支持自定义。

<template>
Scroll down to see the bottom-right button.
<el-backtop target=".page-component__scroll .el-scrollbar__wrap" :bottom="100">
<div
style="{
height: 100%;
width: 100%;
background-color: #f2f5f6;
box-shadow: 0 0 6px rgba(0,0,0, .12);
text-align: center;
line-height: 40px;
color: #1989fa;
}"
>
UP
</div>
</el-backtop>
</template>

如果没试过的可以先跟着官方的文档试下,看是否可行,若不可行,接着往下看

阅读全文 »

mongoDB find

比较符

字符 操作含义 备注
$lt 小于 <
$lte 小于等于 <=
$gt 大于 >
$gte 大于等于 >=
$ne 不等于 !=
$in 在范围内 include {age: {$in: [18,20]}} 注意是数组
$nin 不在范围内 !include 参考$in
$all 完全匹配 { tags: { $all: [tagId] } } 后面接数组
$regex 正则匹配 find({‘name’: {$regex: ‘^M.*}) 以 M 开头的名字
$exists 是否存在 {name:{$exists:true}} 查找 name 存在的 doc
$type 类型判断 {age: {$type: Number}}
$text 文本查询 {$text: {‘$search’: ‘Mike’}} text类型的属性中包含Mike字符串
$or 或操作 {$or:[{‘name’:’chen’},{‘name’:’wang’}]} or 后面接数组
$and 与操作 {$and:[{‘name’:’chen’},{‘name’:’wang’}]} and 后面接数组

$in$all 的区别:

$in$all后面都是接数组,但是指向的范围不同

1
2
3
// 查询topic.tags.includes(copyTagId)的模板,$all 是完全匹配
// 也就是说 topic.tags>= $all 后面的数组
const topicList = await ctx.model.Topic.find({ tags: { $all: [copyTagId] } });
1
2
3
// 查询['1', '2', '3'].includes(topic.name)的模板
// 也就是数据库中的数据等`$in` 后面数组中任何之一都可以,有点像$or
const topicList = await ctx.model.Topic.find({ name: { $in: ['1', '2', '3'] } });

JavaScript 中的 call()和apply()

在JavaScript中,每个函数都包含两个非继承而来的方法:call()和apply()

作用: call和apply的作用都是为了改变某个函数运行时的上下文(context),换句话说,就是为了改变函数体内部this的指向。

1
2
3
4
5
6
7
8
9
10
11
function fruits(){}

fruits.prototype = {
color: "red",
say: function(){
console.log("My color is " + this.color);
}
};

var apple = new fruits;
apple.say(); //My color is red

当想另外一个对象想使用fruits中的say方法时不用重新写,使用call和apply可以实现“劫持”别人的方法。

阅读全文 »