发表于: 2020-02-09 23:20:19
1 1265
一、今天完成的事
<span md-inline="plain" dal框架<="" span="" style="word-break: break-all;">
1.配置group.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<datasources>
<ds name="gemanticWeibo"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://gemantic.weibo.db:3306/weibo_db?defaultBatchValue=1000&characterEncoding=utf8"
username="root"
password="123456"
maxActive="50"
maxIdle="50"
maxWait="10"
check="true" />
<ds name="weiboDev"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://gemantic.weibo.db:3307/weibo_db?defaultBatchValue=1000&characterEncoding=utf8"
username="weibo"
password="weibo_sy31"
maxActive="50"
maxIdle="50"
maxWait="10"
check="true" />
<ds name="idCenterDS"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://gemantic.weibo.db:3306/weibo_db?defaultBatchValue=1000"
username="root"
password="123456"
maxActive=""
maxIdle=""
maxWait=""
check="true" />
</datasources>
<groups>
<group name="gemanticWeibo" master="gemanticWeibo" />
<group name="weiboDev" master="weiboDev" />
</groups>
</root>
2.配置daoConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<dal>
<list>
<config>
<path>companyEvent_dao.xml</path>
</config>
</list>
<default>
<dbStrategy name=""
clasz="com.gemantic.dal.route.strategy.DefaultStrategy">
<pattern value="[0-9]$" group="g1" />
</dbStrategy>
<listenerClass className="" />
<idCenterDS ds="idCenterDS" />
</default>
</dal>
3.配置sql
<?xml version="1.0" encoding="UTF-8"?>
<dal>
<route>
<object name="com.gemantic.gemantic.weibo.model.CompanyEvent"
listenerClass="" strategyProperty="">
<list name="getEidsByCompanyUri" sqlitem="select eid from company_event where company_uri = ?"
keyProperty="companyUri" valueProperty="eid" keyColumn="company_uri" />
<dbStrategy name="mutiDS"
clasz="com.gemantic.dal.route.strategy.DefaultStrategy">
<pattern value="[0-9]$" group="gemanticWeibo" />
</dbStrategy>
</object>
</route>
</dal>
4.配置memcached_client.xml
<region name="com.gemantic.labs.killer.model.MineTrain"
listenerClass="com.gemantic.dal.cache.listener.DefaultListenerImpl"
strategyClass="com.gemantic.memcached.route.strategy.DefaultStrategy">
<keyPattern value="[0-9]$" datasource="default" />
</region>
<region name="getUsersIdByOpenID"
listenerClass="com.gemantic.dal.cache.listener.DefaultListenerImpl"
strategyClass="com.gemantic.memcached.route.strategy.DefaultStrategy">
<keyPattern value="[0-9]$" datasource="default" />
</region>
5.配置model映射关系
public class Video implements Serializable {
public Long id;
public String title;
public String videoImage;
public Long grade;
public Long subject;
public Long classification;
public Integer numberOfLikes;
public Integer numberOfCollections;
public String videoUrl;
public String content;
public String introduction;
public Long status;
public Long collectAt;
public Long createAt;
public Long updateAt;
public String createBy;
public String updateBy;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "title")
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Column(name = "video_image")
public String getVideoImage() {
return videoImage;
}
public void setVideoImage(String videoImage) {
this.videoImage = videoImage;
}
@Column(name = "grade")
public Long getGrade() {
return grade;
}
public void setGrade(Long grade) {
this.grade = grade;
}
@Column(name = "subject")
public Long getSubject() {
return subject;
}
public void setSubject(Long subject) {
this.subject = subject;
}
@Column(name = "classification")
public Long getClassification() {
return classification;
}
public void setClassification(Long classification) {
this.classification = classification;
}
@Column(name = "number_of_likes")
public Integer getNumberOfLikes() {
return numberOfLikes;
}
public void setNumberOfLikes(Integer numberOfLikes) {
this.numberOfLikes = numberOfLikes;
}
@Column(name = "number_of_collections")
public Integer getNumberOfCollections() {
return numberOfCollections;
}
public void setNumberOfCollections(Integer numberOfCollections) {
this.numberOfCollections = numberOfCollections;
}
@Column(name = "video_url")
public String getVideoUrl() {
return videoUrl;
}
public void setVideoUrl(String videoUrl) {
this.videoUrl = videoUrl;
}
@Column(name = "content")
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Column(name = "introduction")
public String getIntroduction() {
return introduction;
}
public void setIntroduction(String introduction) {
this.introduction = introduction;
}
@Column(name = "status")
public Long getStatus() {
return status;
}
public void setStatus(Long status) {
this.status = status;
}
@Column(name = "collect_at")
public Long getCollectAt() {
return collectAt;
}
public void setCollectAt(Long collectAt) {
this.collectAt = collectAt;
}
@Column(name = "create_at")
public Long getCreateAt() {
return createAt;
}
public void setCreateAt(Long createAt) {
this.createAt = createAt;
}
@Column(name = "update_at")
public Long getUpdateAt() {
return updateAt;
}
public void setUpdateAt(Long updateAt) {
this.updateAt = updateAt;
}
@Column(name = "create_by")
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
@Column(name = "update_by")
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
@Override
public String toString() {
return "Video{" +
"id=" + id +
", title='" + title + '\'' +
", videoImage='" + videoImage + '\'' +
", grade=" + grade +
", subject=" + subject +
", classification=" + classification +
", numberOfLikes=" + numberOfLikes +
", numberOfCollections=" + numberOfCollections +
", videoUrl='" + videoUrl + '\'' +
", content='" + content + '\'' +
", introduction='" + introduction + '\'' +
", status=" + status +
", collectAt=" + collectAt +
", createAt=" + createAt +
", updateAt=" + updateAt +
", createBy='" + createBy + '\'' +
", updateBy='" + updateBy + '\'' +
'}';
}
}
二、遇到的问题
三、收获
JWT简单介绍
WT(json web token)
是一种为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准. JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息.
JWT构成
JWT由三段信息构成,这三段信息用.连接起来就构成了jwt字符串
例如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
三部分分别是:头部,载荷和签名
1)头部包含两部分信息:
声明类型,这里是jwt
声明加密的算法 通常直接使用 HMAC SHA256
例如
{
'typ': 'JWT',
'alg': 'HS256'
}
进行base64加密后:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2)载荷
存放有效信息的地方,包含三部分信息:
标准中注册的声明
公共的声明
私有的声明
例如:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
同样进行base64加密:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
3)签名
三部分信息组成:
base64加密后的header
base64加密后的payload
以及secret(secret是用来进行jwt的签发和jwt的验证的,它就是你服务端的私钥,在任何场景都不应该流露出去。)
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
这三个部分拼接成一个完整的字符串,就构成最终的jwt:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
拦截器、过滤器、监听器各有什么作用?
过滤器作用
1 url级别权限访问 控制
2 过滤敏感词汇
3压缩响应信息
4统一字符集
拦截器作用
1.大部分过滤器能做得事情
2.捕获异常,获得bean对象
3.通常用来进行权限验证,判断用户是否登录
监听器作用
1监听servletContext,HttpSession和servletRequest得域对象得创建和销毁时间以及属性发生修改事件。
2统计在线人数和在线用户
3系统启动时加载初始化信息
4统计网站访问量
拦截器,过滤器和监听器的区别
首先执行顺序是 监听器 > 过滤器 > 拦截器
区别主要在 实现原理,生命周期,作用,作用范围上
过滤器:
1.依赖于servlet容器
2.实现上基于函数回调,能对几乎所有请求进行过滤
3.一个过滤器实例只能在容器初始化时调用一次
4.使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,过滤低俗文字,危险字符等.
拦截器:
1.依赖于web框架,在springMVC中就是依赖于SpringMVC框架.
2.在实现上基于Java的反射机制,属于面向切面编程AOP的一种应用
3.只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求无法进行拦截处理
4.拦截器是基于web框架的调用,因此可以使用Spring的依赖注入DI进行一些业务操作,同时一个拦截器实例在一个controller生命周期内可以多次调用
监听器:
监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,例如在观察者模式中就会使用到.
监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行。
1.实现了javax.servlet.ServletContexListener接口的服务器端程序
2.随web应用的启动而启动,随web应用的停止而销毁
3.只初始化一次
4.主要作用是:做一些初始化的内容添加工作,
什么叫明文,什么叫密文,为什么不允许在数据库里明文保存密码?
明文:没有加密过的文字密码
密文:加过密的文字密码
用明文保存密码有很大的信息安全隐患,因为在实际应用场景中,经常有数据库泄露,源代码泄露等风险,因此要对数据库内容进行加密保存,例如对密码进行md5加盐加密保存等.
Cookie的失效时间怎么设定?最大允许存放多少字节?
使用cookie.setMaxage()来设置cookie的生命周期。
默认是-1,即关闭浏览器后cookie失效.
最大允许存放字节各浏览器都不一样,一般在4000左右.例如谷歌浏览器每个域为53个cookie,大小为4097个字节
在App中没有Cookie,怎么解决用户身份识别的问题?Token应该放在什么位置?怎么在后端设计的时候,又支持Cookie,又支持Token?
手机端会话保持可以使用token:登录成功便签发token,以后每次请求都要带上token.
token可存放在session中.
什么叫加盐?加盐能解决什么问题?通常的加盐方式有哪些?
在数据库中保存敏感信息时,常用到md5等算法加密后保存.这样初看上去很安全,例如md5加密的若碰撞性,强离散性等.但存在使用彩虹表暴力破解的可能.
因此,在每个用户的密码中加入一些随机字符串后再加密生成摘要, 解密难度就成指数级增加.加入的随机字符串就是盐.
盐salt有很多选择,可以选择用户名,邮箱,昵称等任意非空字符串或数字,但最安全的还是使用安全的伪随机数生成器生成随机字符串,并保证用户的盐各不相同.
什么叫MD5,MD5通常做什么用处,为什么MD5不可逆,用做密码加密的时候仍然可能会被解密?
md5全称md5信息摘要算法
可以将整个文件当做一个大文本信息,通过不可逆的字符串变换算法,产生一个唯一的MD5信息摘要,该md5值是全世界独一无二的,文件的任何变动也会导致md5值的变化,因此可以用此保证文件的数据一致性.
于是可用md5对密码做加密存储:用户设置密码时,服务端只需保存这个密码的md5而忽略密码本身,以后验证用户身份时,将输入密码的md5与之前的md5比较即可检验密码合法性.
md5特性:
- 不可逆,无法得知某md5值原来的字符串是什么
- 高度离散型,原信息的细微变化也会导致md5发生巨大变化
- 压缩性,md5值长度固定,无论原数据长度如何
- 弱碰撞性,已知原数据和其md5值,想找到一个具有相同md5值的数据非常困难
因为可使用彩虹表去逆向查找,这样对于简单的密码可以破解.
拦截器是什么?为什么要配置拦截器?拦截器里通常应该校验什么,怎么做到统一配置拦截器,让必须登录才能使用的接口,判断用户未登录时,返回错误信息?
拦截器是用于当前用户访问非公开内容时,检测用户的登录状态,如果已经登录,通过验证后可以正常访问。拦截器或者中校验的是cookie信息。配置拦截器的拦截url,同时配设置controller(需要登录才能访问的)的url与拦截规则一致。
java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action
执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。在AOP中,拦截器用于在某个方法或者字段被访问之前,进行拦截
然后再之前或者之后加入某些操作。
Https是什么?怎么配置Https证书,哪些请求需要Https,登录是否需要Https?
1)http全称是超文本传输协议,https全称是安全超文本传输协议,是在http协议基础上增加使用了SSL加密传送信息的协议.通过https传输的内容是经过加密的.
2)ssl证书通常分为三大类,他们安全性递增,价格也递增:
DV (Domain Validation Certificate) 适合个人网站使用,申请证书时,CA 只验证域名信息。几分钟之内就能签发。
OV ( Organization Validation Certificate) 需要认证公司的信息。1-2天签发。
EV ( Extended Validation Certificate) 认证最为严格,一般会要求提供纸质材料。签发时间也较久。
nginx配置ssl:
Nginx默认选项安装没有SSL模块,需要重新编译安装SSL模块
使用命令./configure --prefix=/usr/local/nginx --with-http_ssl_module 安装Nginx并安装SSL模块
把下载下来的证书中Nginx文件夹下的两个文件放在服务器中一个自己能找到的地方
http默认使用80端口,http默认使用443端口,配置好监听的端口并制定证书和秘钥文件
server {
listen 443 ssl;
server_name www.joeeeee.xyz;
root /usr/share/nginx/html;
ssl_certificate "1_joeeeee.xyz_bundle.crt";
ssl_certificate_key "2_joeeeee.xyz.key";
然后重启Nginx使用https就可以进行访问了
3)哪些请求需要https?对于需要传递敏感信息的请求最好使用https,增加安全性.我认为登录应该使用https,防止用户密码被拦截后泄露.
什么是对称加密,什么是非对称加密?分别适用于什么场景?
对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。
对称加密通常使用的是相对较小的密钥,一般小于256 bit。因为密钥越大,加密越强,但加密与解密的过程越慢。如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密,不行的话就再用1解;但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性,也要照顾到效率,是一个trade-off。
非对称加密为数据的加密与解密提供了一个非常安全的方法,它使用了一对密钥,公钥(public key)和私钥(private key)。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。非对称加密使用这对密钥中的一个进行加密,而解密则需要另一个密钥。比如,你向银行请求公钥,银行将公钥发给你,你使用公钥对消息加密,那么只有私钥的持有人--银行才能对你的消息解密。与对称加密不同的是,银行不需要将私钥通过网络发送出去,因此安全性大大提高。
Token的构造规则是什么,怎么确认用户身份的,怎么保证Token被偷窃的问题?
Cookie是在Http的什么位置存放,Cookie里的键可以重复吗?
Cookie在http的请求头中存放。
Cookie的键名是可以重复的。
什么是session?什么是cookie?session和cookie有什么区别?什么场景适用于session?什么场景适用于cookie?
HTTP是无状态协议,也就是没有记忆力的协议,每个请求之间无法共享数据。
这就无法知道会话什么时候开始,什么时候结束,也无法确定发出请求的用户身份。这说明需要使用额外的手段来跟踪会话
服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。
这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。
Session是在无状态的HTTP协议下,服务端记录用户状态时用于标识具体用户的机制。
它是在服务端保存的用来跟踪用户的状态的数据结构,可以保存在文件、数据库或者集群中。在浏览器关闭后这次的Session就消失了,下次打开就不再拥有这个Session。
其实并不是Session消失了,而是Session ID变了,服务器端可能还是存着你上次的Session ID及其Session 信息,只是他们是无主状态,也许一段时间后会被删除。
什么是cookie?
Cookie是HTTP协议的规范之一,它是服务器和客户端之间传输的小数据。
* 首先由服务器通过响应头把Cookie传输给客户端,客户端会将Cookie保存起来。
* 当客户端再次请求同一服务器时,客户端会在请求头中添加该服务器保存的Cookie,发送给服务器。
* Cookie就是服务器保存在客户端的数据!
* Cookie就是一个键值对!!!
cookie主要包括:
名字:name,必选参数,这个是cookie的变量名
值:value,可选参数,这个cookie变量的值
过期时间:cookie的生命周期,以秒为单位,Cookie.setMaxAge()
cookie.setmaxage设置为0时,会马上在浏览器上删除指定的cookie
cookie.setmaxage设置为-1时,代表关闭当前浏览器即失效。
如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了
路径:路径就是跟在域名后面的URL路径,一般设置为”/“,Cookie.setPath("/");
session和cookie区别?
1、Cookie 在客户端(浏览器),Session 在服务器端。
2、Cookie的安全性一般,他人可通过分析存放在本地的Cookie并进行Cookie欺骗。在安全性第一的前提下,选择Session更优。重要交互信息比如权限等就要放在Session中,一般的信息记录放Cookie就好了。
3、单个Cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie。
4、Session 可以放在 文件、数据库或内存中,比如在使用Node时将Session保存在redis中。由于一定时间内它是保存在服务器上的,当访问增多时,会较大地占用服务器的性能。考虑到减轻服务器性能方面,应当适时使用Cookie。
5、Session 的运行依赖Session ID,而 Session ID 是存在 Cookie 中的,也就是说,如果浏览器禁用了 Cookie,Session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 Session ID)。
6、用户验证这种场合一般会用 Session。因此,维持一个会话的核心就是客户端的唯一标识,即Session ID。
什么场景适用于session?什么场景适用于cookie?
cookie
用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
只要添加了就一直存在,只要不是手动的去清除或者expires为默认的过期时间。但是安全性无法保证,而且也无法对客户的喜好进行定量的分析,有个数和长度的限制。
session
对话的时效性的问题,如果客户选购商品的途中浏览器突然关闭,服务端找不到cookie中的sessionid了,那么选购的商品就不存在了
session是实现购物车的另一种方法。session提供了可以保存和跟踪用户的状态信息的功能,使当前用户在session中定义的变量和对象能在页面之间共享,但是不能为应用中其他用户所访问,
它与cookie最重大的区别是,session将用户在会话期间的私有信息存储在服务器端,提高了安全性。在服务器生成session后,客户端会生成一个sessionid识别号保存在客户端,以保持和服务器的同步。
这个sessionid是只读的,如果客户端禁止cookie功能,session会通过在URL中附加参数,或隐含在表单中提交等其他方式在页面间传送。因此利用session实施对用户的管理则更为安全、有效。
四、明天的计划
代码自动生成
评论