0%

1. 安装

wget http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.5.3/binaries/apache-maven-3.5.3-bin.tar.gz

2. pom结构

  • groupId
  • artifactId
  • version
  • package
    jar | war | pom
  • dependencies
    • groupId
    • artifactId
    • version
    • scope
      • compile: 编译,测试,运行都有效, 默认范围
      • provided: 在编译和测试时有效
      • runtime: 在测试和运行时有效
      • test: 只在测试时有效
      • system: 在编译和测试时有效, 与本机系统关联, 可移植性差
    • optional
      true | false , 是否排除依赖.
      例如, 如果ProjectA中配置依赖ProjectB, 并且optional:true, 那当ProjectX依赖ProjectA时, 如果没有显示的引入ProjectB, 则ProjectX不会引入ProjectB, 即ProjectX可以自己选择是否依赖ProjectB.

3. 添加maven镜像

在settings.xml的mirrors节点下添加

1
2
3
4
5
6
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

或者在pom.xml的profiles/profile节点添加

1
2
3
4
5
6
7
8
9
10
11
12
<repository>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<layout>default</layout>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>

4. 上传jar文件到私服

1
mvn deploy:deploy-file -DgroupId=com.google.code.kaptcha -DartifactId=kaptcha -Dversion=2.3 -Dpackaging=jar -Dfile=/home/raven/Workspace/TomatoDocs/kaptcha-2.3.jar -Durl=http://10.18.75.202:8081/nexus/content/repositories/snapshots/ -DrepositoryId=snapshots

– DgroupId和DartifactId构成了该jar包在pom.xml的坐标, 对应依赖的DgroupId和DartifactId
– Dfile表示需要上传的jar包的绝对路径
– Durl私服上仓库的url精确地址(打开nexus左侧repositories菜单, 可以看到该路径)
– DrepositoryId服务器的表示id, 在nexus的configuration可以看到

5. 常用插件

5.1. Project Build Plugins

GroupId ArtifactId Version
com.mycila license-maven-plugin 3.0
net.revelc.code.formatter formatter-maven-plugin 2.0.1
org.apache.maven.plugins maven-antrun-plugin 1.8
org.apache.maven.plugins maven-assembly-plugin 3.0.0
org.apache.maven.plugins maven-clean-plugin 3.0.0
org.apache.maven.plugins maven-compiler-plugin 3.6.1
org.apache.maven.plugins maven-dependency-plugin 3.0.1
org.apache.maven.plugins maven-deploy-plugin 2.8.2
org.apache.maven.plugins maven-install-plugin 2.5.2
org.apache.maven.plugins maven-javadoc-plugin 2.10.4
org.apache.maven.plugins maven-pdf-plugin 1.3
org.apache.maven.plugins maven-release-plugin 2.5.3
org.apache.maven.plugins maven-resources-plugin 3.0.2
org.apache.maven.plugins maven-shade-plugin 3.0.0
org.apache.maven.plugins maven-site-plugin 3.6
org.apache.maven.plugins maven-surefire-plugin 2.20
org.codehaus.mojo versions-maven-plugin 2.4
org.eluder.coveralls coveralls-maven-plugin 4.3.0
org.jacoco http://jacoco-maven-plugin 0.7.9

5.2. Project Report Plugins

GroupId ArtifactId Version
org.apache.maven.plugins maven-changes-plugin 2.12.1
org.apache.maven.plugins maven-checkstyle-plugin 2.17
org.apache.maven.plugins maven-javadoc-plugin 2.10.4
org.apache.maven.plugins maven-jxr-plugin 2.5
org.apache.maven.plugins maven-pmd-plugin 3.8
org.apache.maven.plugins maven-project-info-reports-plugin 2.9
org.apache.maven.plugins maven-surefire-report-plugin 2.20
org.codehaus.mojo clirr-maven-plugin 2.8
org.codehaus.mojo findbugs-maven-plugin 3.0.4
org.codehaus.mojo jdepend-maven-plugin 2.0
org.codehaus.mojo taglist-maven-plugin 2.4
org.codehaus.mojo versions-maven-plugin 2.4
org.jacoco http://jacoco-maven-plugin 0.7.9

6. 常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -f 指定 mvn 命令工作目录, 在该目录下必须要有 pom.xml 文件
mvn clean install -f <pom-dir>

# -pl 单独编译哪些模块, 可以用逗号隔开
# -am 同时编译 `-pl 列举的模块依赖的模块`
# -amd 同时编译`依赖 -pl 列举的模块`
# -N 不递归, 常用在只构建父 pom
mvn clean install -pl .,<sub-project> -am

# 查看依赖树
mvn dependency:tree

# 依赖分析, 删除无用的依赖
# http://maven.apache.org/components/plugins/maven-dependency-plugin/
mvn dependency:analyze

7. 常用配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>project.build.sourceEncoding</encoding>
</configuration>
</plugin>
</plugins>
</build>

8. 常见问题

8.1. 带 @SpringApplication 的模块打包后, 在别的项目中引入时, 无法找到模块中的类

在jar包中看到, 编译文件在 BOOT-INF 目录下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier> <!--加上这个就可以, 但是会变成无法执行-->
<mainClass>${mainClass}</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>

Open Web Application Security Project

https://wenku.baidu.com/view/ac06092af18583d049645968.html
安全测试
安全测试更有说服力, 有些问题是无法通过代码审查发现的, 尤其是应用程序架构方面的问题.安全测试通过展示一个可实现的攻击来证明应用程序是不安全的.目前安全测试主要是通过漏洞扫描工具来进行的, 比如Netsparker, ZAP等

1. Resource

0.0.1. 主键自增, 并按特定格式的

主键不支持varchar自增, 所以需要拼接英文字符串的只能在程序里控制.

假如主键仍是数字, 比如需要一个定长4为的ID, 可以使用以下方式:

1
2
3
4
5
6
7
CREATE TABLE `auto` (                                     
`id` int(4) unsigned zerofill NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


insert into auto select NULL;

主键步长和偏移量可以根据需要更改.

1. InnoDb 下为什么用自增列作为主键

InnoDB 无法自定义选择哪一列作为聚簇索引, 而是默认选择主键作为聚簇索引.
如果表中没有定义了主键, 则会选择没有 NULL 值的唯一索引在作为聚簇索引; 如果没有符合条件的唯一索引, 则会选择内置的 6 字节长度的 ROWID 作为聚簇索引. ROWID 是随行写入而逐渐递增的.

在聚簇索引中, 数据记录存放在主索引 (B+Tree) 的叶子节点上. 所有叶子节点会根据 KEY 值按顺序存放.

更新聚簇索引可能面临 页分裂 的问题.
如果主键非自增, 当插入新的记录时, 加入新记录的 KEY 需要插入某个已满的页中, 存储引擎就会将该页分裂成两个页面来容纳这条记录.
如果更新主键列, 存储引擎就需要将该行移动到新的位置, 同样可能面临这个问题.
这就会导致磁盘碎片的产生.
可以使用 OPTIMIZE TABLE 命令重新组织表结构.

那么如果是自增主键, 则每次插入新的记录时, 就可以顺序添加到当前索引节点的后续位置. 所以按主键顺序插入是加载数据到 InnoDB 表中速度最快的方式.
至少保证了插入的速度. 而一般不会有更新主键的情况, 最多出现更新唯一索引的情况.

2. 既然 varchar 是可变长度的, 那么只有存得下内容, 如 ‘hello’ , 那 varchar(5) 比 varchar(500) 好在哪里?

由于 varchar 是可变长度的, 那他们的存储开销是一样的
但是在内存的中消耗不一样, 随之带来的是排序与操作时的消耗更大.

CSRF, Cross-Site Request Forgerr, 跨站请求伪造.
一般我们认为:如果请求的发出不是用户的意愿, 那么这个请求就是伪造的.

1. 攻击原理

  1. 用户访问正常网站A, 并获得授权
  2. 用户未退出网站A, 并且访问了恶意网站B
  3. 浏览器自动触发恶意网站B中的恶意请求–跨站访问网站A
  4. 网站A收到请求, 认为用户以获得授权, 请求合法并执行.

2. 攻击类型

  • HTML CSRF
    使用HTML元素发起攻击.
    是最普遍的CSRF攻击方式.
  • JSON HiJacking
  • Flash CSRF

3. 危害

  • 篡改目标网站上的用户数据
  • 盗取用户隐私数据
  • 作为其他攻击向量的辅助攻击手法
  • 传播CSRF蠕虫

4. CSRF防御

  • 验证码
    会影响用户体验.
  • 验证请求头中的referer
    浏览器中有防止信息追踪策略, 请求不会带上referer, 导致误判.
  • token凭证
    token为服务器端提供的随机秘钥, 攻击者无法伪造.
    服务器先给浏览器提供token, 用户提交请求后, 验证token有效性, 在处理请求;若没有token或token不正确, 则判定为CSRF攻击, 拒绝请求.

XSS, Cross Site Scripting, 跨站脚本攻击.

1. 攻击类型

有3种攻击类型:

1.1. 反射型 XSS

发出请求时, XSS代码出现在URL中, 作为输出提交到服务器端, 服务器端解析后响应, XSS代码随响应内容一期传给浏览器, 最后浏览器解析XSS代码.
这个过程像一次反射, 故叫做反射型XSS.

1.2. 存储型 XSS

存储型XSS和反射型的差别仅在于:提交的代码会存储在服务器端(数据库, 内存, 文件系统等), 下次请求目标页面时不用再提交XSS代码.

1.3. DOM XSS

DOM XSS和反射型 XSS, 存储型 XSS的差别在于:DOM XSS的XSS代码并不需要服务器解析响应的直接参与, 触发XSS靠的就是浏览器短的DOM解析, 可以认为完全是客户端的事情.

2. 危害

  • 挂马
  • 盗取用户Cookie
  • Dos客户端浏览器
  • 钓鱼攻击, 高级钓鱼技巧
  • 编写正对性的XSS病毒, 删除目标文章, 恶意篡改数据, 嫁祸
  • 劫持用户Web行为, 甚至进一步参透内网
  • 爆发Web2.0蠕虫
  • 蠕虫式DDos攻击
  • 蠕虫式挂马攻击, 刷广告, 刷流量, 破坏网上数据

3. XSS 防御

  • 编码
    对用户输入的数据进行HTML Entity编码.
字符 转义字符
& &
< <
> >
" "
'
/ /
空格  
  • 过滤
    对用户上传的不安全的内容进行过滤, 比如:
    • 移除用户上传的DOM属性, 如onerror, onclick等.
    • 移除用户上传的style, script, img, iframe等节点.
  • 校正
    • 避免直接对HTML Entity解码.
    • 使用DOM Parse转换, 校正不配对的DOM标签.

4. Resource

1. 关闭右侧标签页时候不会出现提示对话框

about:config
browser.tabs.warnOnCloseOtherTabs false

0.0.1. Intro

  1. 接口文档
    不需要格式转换, 变更标注, 文档分发
  2. 接口用例
    可直接生成查看
  3. 前端Mock测试
    在前后端分离的架构下, 前端使用mock测试, 促使前后端可以

0.0.2. Set up

0.0.2.0.1. RAP war
1
wget http://rapapi.org/release/RAP-0.14.16-SNAPSHOT.war
0.0.2.0.2. tomcat
1
wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.23/bin/apache-tomcat-8.5.23.tar.gz
0.0.2.0.3. redis
1
sudo apt install redis-server

0.0.3. Resource

SSO, Single Sign On, 单点登录

1. 应用场景

大型Web项目一般都有这样的开发场景:

  • 项目子系统众多, 需要一个统一的登录系统, 用户只需要登录一次就可以访问其他信任的子系统应用.
  • 子系统间依赖复杂, 前端页面间有相互跳转需求.
  • 前后端分离, 各个系统间需要跨域访问.

2. 单点登录序列图

  • ticket
    SSO系统发放给前端页面的登录凭证, 之后交给子系统判断其有效性.
    为了防止被拦截, ticket的存活时间极短, 一般设置为5秒左右.
  • sid
    即Session ID, 用户登录成功后的会话ID.
    同一用户在各个系统间获得的sid应该不同, 以防止某个子系统泄露sid而影响其他子系统.
    用户与sid之间是一对多的关系.
  1. 用户在浏览器触发任意请求访问子系统.
  2. 子系统验证请求的Cookie中是否有sid.
    假设目前为首次登录, Cookie为空, 则返回未登录状态.
  3. 子系统页面跳转到SSO系统的登录页面.
  4. 用户输入相关登录信息(用户名, 密码, 验证码等), 请求登录验证.
  5. SSO系统验证用户信息, 生成ticket及用户信息;返回结果中将sid写入Cookie, 用于免登, 防止用户重复登录.
  6. 浏览器跳转到回调页面, 该页面用于统一验证ticket, 可设计成空白页面.
    若不用回调页面, 则需要每个页面都有处理ticket的能力.
  7. 浏览器向子系统请求验证ticket.
  8. 子系统向SSO系统请求验证ticket.
  9. SSO系统验证完成后销毁ticket, 并为子系统生成sid.
    该sid与之前步骤5的sid不同, 原因之前已说明.
  10. 子系统缓存用户相关信息, 返回登录状态.
  11. 浏览器重新跳转到原url, 触发任意请求.
  12. 子系统验证Cookie中是否sid.
    若之前步骤都成功, 则此时Cookie一定带有sid.
  13. 子系统从本地缓存中获取用户信息.
    用户信息缓存时间不宜过长, 避免用户长时间不操作或不友好退出后, 占用缓存空间资源.
    若无缓存信息, 则向SSO系统获取.
  14. 子系统向SSO系统获取用户权限列表.
    此步骤也可做缓存处理, 同样缓存时间也不宜过长.
  15. SSO系统查询并返回用户权限列表.
  16. 子系统正常处理请求并返回处理结果.

3. 缓存内容

sid --n–1--> userid, loginTime, SubModuleID
userid --1–1--> userInfo, permissionList

4. 安全问题

  1. ticket与sid应使用uuid类型的字符串, 防止暴力破解
  2. 为了防止被拦截, ticket的存活时间极短, 一般设置为5秒左右.
  3. 同一用户在各个系统间获得的sid应该不同, 以防止某个子系统泄露sid而影响其他子系统.
  4. 缓存设置时间不宜过长, 一方面避免占用空间资源, 另一方面防止回话被劫持.可以用户触发接口后延期, 但到一定时间后必须销毁.
  5. 在修改用户重要信息或权限后, 自动登出.
  6. CSRF攻击
  7. XSS攻击
  8. 日志记录用户操作, 无论成功还是失败, 防御各种攻击.

5. 性能问题

  1. 缓存时间过不宜过短, 防止接口频繁调用, 缓存频繁写入.

6. 迭代开发

迭代开发BOSS系统, 在统一的系统页面可以管理所有子系统, 不用在不同的系统中跳转, 方便运维.

7. Resource

1. 快捷键配置

1
2
3
4
5
'atom-text-editor':
'ctrl-shift-l': 'editor:split-selections-into-lines'

'.platform-linux atom-text-editor':
'ctrl-shift-g': 'grammar-selector:show'

2. 修改源

为了加快包安装速度, 添加~/.apmrc

1
2
registry=https://registry.npm.taobao.org/  
strict-ssl=false

3. 插件

  • advanced-open-file
  • atom-beautify
  • last-cursor-position
  • markdown-preview-enhanced
  • markdown-writer
  • minimap
  • open-in-browser
  • pdf-view
  • platformio-ide-terminal
  • sort-lines 行排序
  • tree-view-git-status
  • atom-ide-ui
  • file-icons
  • todo-show

4. Resource