Hello DiDi!
你好,滴滴!你好,橙心!
Hello Ren Ren!
给Linux带上Google Authenticator安全套
先说说什么是Google Authenticator(以下简称GA),你可以把它想成开源的QQ手机令牌,基于时间和一定的算法生成6位动态口令。
mac安装phpMyAdmin管理mysql数据库
在macbook系统上安装phpMyadmin工具管理mysql数据库。
环境
- macOS 10.12.1 (mysql5.7官方说支持到10.11,其实这个版本也可以安装)
- mysql5.7.16
- apache2.4.23 (macOS自带)
- PHP5.6.25 (macOS自带)
- MySQL Workbench (GPL)6.3.8
- phpMyAdmin4.4.10
安装mysql
- 这里选择mac版mysql5.7.16(发帖最高)版本,通过Oracle官网下载
- 安装后注意弹窗,会提示默认的初始密码,接下来会用到改密码初始化数据库。
安装MySQL Workbench工具初始化mysql数据库root账户
- 在上一步mysql下载页面的下方会找到MySQL Workbench的下载链接,下载并安装
- 启动软件,添加一个本地mysql数据库连接会话。输入初始密码后会提示密码未修改。再次提交后会提示输入Oldpassword和输入两次新密码。完成后 root账户到此初始化成功
将phpMyAdmin源码放入web主目录
目录地址:/Library/WebServer/Documents/ 为apache 的www目录
开启mac本地apache和php环境
使用 终端su命令输入密码后切换管理员账号,并输入一下命令
1 | nano /etc/apache2/httpd.conf |
找到以下信息并修改
1 | #LoadModule php5_module libexec/apache2/libphp5.so |
配置phpMyAdmin
复制配置文件
1 | cp config.sample.inc.php config.inc.php |
修改权限
1 | chmod -R 777 /Library/WebServer/Documents/phpmyadmin/ |
启动apache测试环境
1 | /usr/sbin/apachectl start |
访问 http://localhost/phpmyadmin 输入帐密登录
升级mac系统后git丢失
今天手贱升级max最新系统后,打开Idea提示git环境异常,提示如下信息:
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
完美解决方法:xcode-select –install
Hello GitHub.io
Java中字符串对象真的是不可变的么?
字符串(String)在面试过程中被问到最多的就是“字符串对象为什么是不可变的?”,现在遇到这种题就是送分题了,标准答案网上随便一找有的是。但是,字符串对象真的不可以被改变么?
weixin4j使用之(三) 缓存管理
在微信开发过程中,一些例如jsapi_token 和jsapi_ticket这些信息都有固定的生存时间,过了生存时间即失效,需要重新获取,然而微信方面对于这些信息的获取次数也加以限制。比如jsapi_token的有效时间为7200秒,日最大刷新次数为2000次。如果在每个业务周期内都获取一次的话,很有可能把接口刷爆掉,影响该公众号其他业务。
在传统开发中,上述那些敏感信息主要有以下几种存储形式:外部文件、内存、数据库、高速缓存等。介于一些信息都限制了有效时间,像是文件、内存、数据库这种形式存储的话每次获取前都需要判断一下token距上次获取的时间是否超过keytoken有效时间,若超过则调用token的刷新方法重新获取token。这个逻辑不难,但每次都要判断时间,这个很头疼。
当然,还有最后一种 高速缓存,比如redis,他可以很简单的在插入key的时候设置该key的生存时间,这样一来我们在读key的时候只需要判断有没有就行了,有就用没有就获取,是不是so easy。
好了,逻辑捋清楚了,再来看一下weixin4j给我们提供了哪些缓存的实现。
weixin4j的Token缓存
在此之前,我对该项目的缓存没有任何一点了解,完全出于我个人判断,因为微信开发中必须要涉及到关键性token的缓存问题,那么该框架一定会提供缓存功能,这个方向是对的,那么具体在哪里?怎么用?怎么实现的?如何扩展?就需要翻文档或者查作者源码了。很遗憾,项目官网并没有提供缓存使用方面的文档或介绍,但我在该项目的github主页中找到了一篇介绍,实际上只是说了提供了和默认提供哪种缓存而已,并没有提供别的信息。开启自悟模式。
在基础组件的cache包中,我找到了一组关于缓存的API。
- Cacheable
接口,定义可缓存对象一定是Cacheable的子类实现 - CacheCreator
接口,定义缓存的创建 - CacheStorager
接口,定义缓存的存储。如果要定义自己的缓存存储实现,直接实现该接口即可。但weixin4j已经给我们提供了五个可选择的实现,日常够用。 - CacheManager
缓存管理器,构造时需要传入缓存的创建对象和存储对象。 - 五个常用的缓存存储的实现
很巧,我的思路和作者一样,这里有五种缓存方式的具体实现,与我上面相比,多了一个redis集群配置和Memcache缓存配置,这个就不多说了。他们分别是
- FileCacheStorager 文件方式,是weixin4j默认提供的
- MemoryCacheStorager 内存方式,不推荐使用
- MemcacheCacheStorager Memcache的缓存方式,熟悉的童鞋可以用一下
- RedisCacheStorager 基于单个Redis缓存的配置方式
- RedisClusterCacheStorager Redis集群方式
默认情况下,weixin4j使用文件方式,即使用FileCacheStorager来管理token缓存,默认缓存路径:java.io.tmpdir。
Redis缓存token
五种方式都可以尝试,这里因为项目背景的原因,我使用单个Redis方式配置。
直接看RedisCacheStorager这个类的源码
1 | public class RedisCacheStorager<T extends Cacheable> implements |
在基于单个Redis的token缓存实现中,默认使用本地无密码认证的6379端口的Redis作为缓存介质,但也提供了四个构造方法去创建自己的token缓存。
第一种,直接使用默认的方式,不多说
第二种,使用主机地址、端口、超时时间配置
第三种,直接使用jedis连接池配置对象,但主机地址、端口和超时时间均使用默认
第四种,全部自定义
第五种,直接把jedis连接池对象传入
配置使用
在Weixin4jConfig对象中,加入RedisCacheStorager对象Bean配置。这里我的项目基于SpringBoot,配置如下
1 | @Autowired |
直接将Jedis的连接工厂拿到,配置RedisCacheStorager的时候注入四个信息即可。
在WeixinProxy对象中可以找到这样一个构造函数
1 | public WeixinProxy(CacheStorager<Token> cacheStorager) { |
在构造该对象的时候传入一个Token对象的缓存存储管理器。这里直接在昨天的配置类中Weixin4jProxy的Bean配置处使用该构造函数初始化,并传入一个RedisCacheStorager对象。
1 | @Bean |
测试
调用分享接口,进入redis查看缓存信息
weixin4j使用之(二) JSSDK使用
使用weixin4j第二天,今天搞一下JSSDK,也就是分享到朋友圈,分享到QQ之类的接口,官方称JS接口。废话不说,开干。
微信JS接口开发逻辑
在使用weixin4j进行微信JSSDK开发之前,先熟悉一下sdk的开发逻辑,这样在使用weixin4j的时候如果遇到问题,解决起来比较方便,逻辑也比较清楚。下面捋一下步骤
- 绑定安全域名,没的说
- 编写用于提供前端JSSDK配置信息的后端接口【参数:页面完整带参数url地址,去掉#后部分】
- 拿appid和secret换取access_token(公众号的全局唯一票据)。有效期7200秒,因此需要缓存起来,防治刷爆。此token非彼token,和我们上一篇文章中的token不一样,别混了。这个token是appid和secret加密后的结果,可以理解成该公众号的身份凭证,只不过该凭证每2小时(7200秒)需要刷新一次而已。接下来拿着我们的身份证去换票吧
- 用得到的access_token换取api_ticket。有效期也是7200秒,也需要做缓存。ticket相当于一张门票,在微信的一些接口调用中,都需要拿着这张票才使用。此时我们有了两样东西,一个是身份证(access_token)另一个是门票(api_ticket),他们都有过期时间,我们需要定期去重新获取他们。
- 生成签名
该签名是JSSDK接口的一个调用凭证,80%的错误都来自于签名的生成。- 签名生成需要如下几个参数:
- 被分享页面的完整带参url地址,去掉#后部分,这里已经作为参数传递进来了
- 时间戳,10位字符串
- 随机字符串
- 门票(api_ticket)
- 签名算法,引用微信官方文档
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
- 签名生成需要如下几个参数:
- 将appid、时间戳、随机字符串、签名四个信息返回。到此后端接口就编写完了
- 编写前端JS代码
- 通过后端接口获得配置信息
- 注入微信JSSDK配置函数中
- 在ready函数中配置要调用的JSSDK api信息
逻辑都知道了吧,建议用原生去写一下,一步步按照开发逻辑捋一遍再看这篇文章,就会更清晰一点。这里不再写原生了,直接使用weixin4j快速开发后端接口
weixin4j开发思路
上一篇文章在获取用户信息的时候单独创建了一个配置类Weixin4jConfig,其中配置了开发代理类WeixinProxy,通过看这个Bean的源码,我们发现了如下的方法:
1 | /** |
看到这个方法是关于JSSDK的,而且直接操作的是Ticket,我就乐坏了,哈哈。
不难发现该方法可以获取Ticket票据管理对象,需要传如一个参数TicketType,用我多年体育老师教的英语经验来看,这个参数名叫票据类型,让我们再看一下这个票据类型到底是啥
1 | public enum TicketType { |
这是一个枚举类,发现jsapi,思路清晰了,需要根据票据类型获取票据管理对象。查阅票据管理对象的源代码发现并没有生成签名的算法。
接着沿着我们的思路,我们需要找到一个可以将四个参数生成签名的函数,或者如果weixin4j封装的更完善一点直接传入一个url得到组配置结果信息。
翻源码翻了好一会,发现在weixin4j-base组件com.foxinmy.weixin4j.jssdk包中有两个类,分别是JSSDKAPI和JSSDKConfigurator,真是踏破草鞋无觅处,得来全不费功夫呀
JSSDKConfigurator是真正的JSSDK配置信息的操作对象,而JSSDKAPI对象则是API信息的对象,后续才会用到它,先不着急。来看一下这个对象的结构:
- 该对象有一个构造方法,需要传入一个TokenManager,咦,这个构造函数的注释中说可以通过调用WeixinProxy#getTicketManager获取,兴奋不已。
- debugMode()方法是开启JSSDKdebug模式,该方法只是向返回信息中添加了一个debug为true的参数,很显然,该参数的信息会在前端被使用,我们只需要接受就好
- appid(),其实并没什么卵用,如果在weixin4j配置了开发者账号在初始化的时候直接回从配置文件中获得,这里不管他
- apis(),可以传入一个或一组API数据
- toJSONConfig,这个方法传入一个String类型的url,返回一组信息。这个方法就是我们需要的构造签名的方法,代码找到了,那就开干
配置Bean
根据思路我们知道,使用weixin4j开发JSSDK需要三个组件,一个是TokenManager另一个是JSSDKConfigurator,还有上一篇的WeixinProxy代理类
1 | @Bean |
到此我们的配置工作就结束了, 接着来搞一下api接口
API接口
首先注入刚刚配置的两个Bean
1 | @Autowired |
接着 编写web接口
1 | @GetMapping(value = "jssdk_jsonconfig") |
后端的接口代码就是这样。关键代码就两行,是不是特别一贼
前端JS代码
根据我们的原生开发逻辑,直接上代码,不啰嗦
1 | <!-- js --> |