提交 ced8c21e authored 作者: fit2cloud-chenyw's avatar fit2cloud-chenyw

feat: 公共链接分享

上级 89f0c5e7
......@@ -10,8 +10,15 @@ public class RsaProperties {
public static String privateKey;
public static String publicKey;
@Value("${rsa.private_key}")
public void setPrivateKey(String privateKey) {
RsaProperties.privateKey = privateKey;
}
@Value("${rsa.public_key}")
public void setPublicKey(String publicKey) {
RsaProperties.publicKey = publicKey;
}
}
......@@ -118,6 +118,24 @@ public class JWTUtils {
}
}
public static String signLink(String resourceId, String secret) {
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.create().withClaim("resourceId", resourceId).sign(algorithm);
}
public static boolean verifyLink(String token,String resourceId, String secret) {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withClaim("resourceId", resourceId)
.build();
try {
verifier.verify(token);
return true;
}catch (Exception e){
return false;
}
}
/**
* 获取当前token上次操作时间
* @param token
......
package io.dataease.auth.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.ArrayUtils;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RsaUtil {
......@@ -23,7 +26,39 @@ public class RsaUtil {
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
// byte[] result = cipher.doFinal(Base64.decodeBase64(text));
// 下面该用分段加密
byte[] result = null;
byte[] b = Base64.decodeBase64(text);
for (int i = 0; i < b.length; i += 64) {
byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(b, i,i + 64));
result = ArrayUtils.addAll(result, doFinal);
}
return new String(result);
}
/**
* 公钥加密
*
* @param publicKeyText 公钥
* @param text 待加密的文本
* @return /
*/
public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
/*byte[] result = cipher.doFinal(text.getBytes());*/
// 下面该用分段加密
byte[] result = null;
byte[] b = text.getBytes("utf-8");
for (int i = 0; i < b.length; i += 50) {
byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(b, i,i + 50));
result = ArrayUtils.addAll(result, doFinal);
}
return Base64.encodeBase64String(result);
}
}
......@@ -7,6 +7,8 @@ import lombok.Data;
public class PanelLink implements Serializable {
private String resourceId;
private Boolean valid;
private Boolean enablePwd;
private String pwd;
......
......@@ -174,6 +174,66 @@ public class PanelLinkExample {
return (Criteria) this;
}
public Criteria andValidIsNull() {
addCriterion("`valid` is null");
return (Criteria) this;
}
public Criteria andValidIsNotNull() {
addCriterion("`valid` is not null");
return (Criteria) this;
}
public Criteria andValidEqualTo(Boolean value) {
addCriterion("`valid` =", value, "valid");
return (Criteria) this;
}
public Criteria andValidNotEqualTo(Boolean value) {
addCriterion("`valid` <>", value, "valid");
return (Criteria) this;
}
public Criteria andValidGreaterThan(Boolean value) {
addCriterion("`valid` >", value, "valid");
return (Criteria) this;
}
public Criteria andValidGreaterThanOrEqualTo(Boolean value) {
addCriterion("`valid` >=", value, "valid");
return (Criteria) this;
}
public Criteria andValidLessThan(Boolean value) {
addCriterion("`valid` <", value, "valid");
return (Criteria) this;
}
public Criteria andValidLessThanOrEqualTo(Boolean value) {
addCriterion("`valid` <=", value, "valid");
return (Criteria) this;
}
public Criteria andValidIn(List<Boolean> values) {
addCriterion("`valid` in", values, "valid");
return (Criteria) this;
}
public Criteria andValidNotIn(List<Boolean> values) {
addCriterion("`valid` not in", values, "valid");
return (Criteria) this;
}
public Criteria andValidBetween(Boolean value1, Boolean value2) {
addCriterion("`valid` between", value1, value2, "valid");
return (Criteria) this;
}
public Criteria andValidNotBetween(Boolean value1, Boolean value2) {
addCriterion("`valid` not between", value1, value2, "valid");
return (Criteria) this;
}
public Criteria andEnablePwdIsNull() {
addCriterion("enable_pwd is null");
return (Criteria) this;
......
......@@ -3,6 +3,7 @@
<mapper namespace="io.dataease.base.mapper.PanelLinkMapper">
<resultMap id="BaseResultMap" type="io.dataease.base.domain.PanelLink">
<id column="resource_id" jdbcType="VARCHAR" property="resourceId" />
<result column="valid" jdbcType="BIT" property="valid" />
<result column="enable_pwd" jdbcType="BIT" property="enablePwd" />
<result column="pwd" jdbcType="VARCHAR" property="pwd" />
</resultMap>
......@@ -65,7 +66,7 @@
</where>
</sql>
<sql id="Base_Column_List">
resource_id, enable_pwd, pwd
resource_id, `valid`, enable_pwd, pwd
</sql>
<select id="selectByExample" parameterType="io.dataease.base.domain.PanelLinkExample" resultMap="BaseResultMap">
select
......@@ -98,10 +99,10 @@
</if>
</delete>
<insert id="insert" parameterType="io.dataease.base.domain.PanelLink">
insert into panel_link (resource_id, enable_pwd, pwd
)
values (#{resourceId,jdbcType=VARCHAR}, #{enablePwd,jdbcType=BIT}, #{pwd,jdbcType=VARCHAR}
)
insert into panel_link (resource_id, `valid`, enable_pwd,
pwd)
values (#{resourceId,jdbcType=VARCHAR}, #{valid,jdbcType=BIT}, #{enablePwd,jdbcType=BIT},
#{pwd,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.dataease.base.domain.PanelLink">
insert into panel_link
......@@ -109,6 +110,9 @@
<if test="resourceId != null">
resource_id,
</if>
<if test="valid != null">
`valid`,
</if>
<if test="enablePwd != null">
enable_pwd,
</if>
......@@ -120,6 +124,9 @@
<if test="resourceId != null">
#{resourceId,jdbcType=VARCHAR},
</if>
<if test="valid != null">
#{valid,jdbcType=BIT},
</if>
<if test="enablePwd != null">
#{enablePwd,jdbcType=BIT},
</if>
......@@ -140,6 +147,9 @@
<if test="record.resourceId != null">
resource_id = #{record.resourceId,jdbcType=VARCHAR},
</if>
<if test="record.valid != null">
`valid` = #{record.valid,jdbcType=BIT},
</if>
<if test="record.enablePwd != null">
enable_pwd = #{record.enablePwd,jdbcType=BIT},
</if>
......@@ -154,6 +164,7 @@
<update id="updateByExample" parameterType="map">
update panel_link
set resource_id = #{record.resourceId,jdbcType=VARCHAR},
`valid` = #{record.valid,jdbcType=BIT},
enable_pwd = #{record.enablePwd,jdbcType=BIT},
pwd = #{record.pwd,jdbcType=VARCHAR}
<if test="_parameter != null">
......@@ -163,6 +174,9 @@
<update id="updateByPrimaryKeySelective" parameterType="io.dataease.base.domain.PanelLink">
update panel_link
<set>
<if test="valid != null">
`valid` = #{valid,jdbcType=BIT},
</if>
<if test="enablePwd != null">
enable_pwd = #{enablePwd,jdbcType=BIT},
</if>
......@@ -174,7 +188,8 @@
</update>
<update id="updateByPrimaryKey" parameterType="io.dataease.base.domain.PanelLink">
update panel_link
set enable_pwd = #{enablePwd,jdbcType=BIT},
set `valid` = #{valid,jdbcType=BIT},
enable_pwd = #{enablePwd,jdbcType=BIT},
pwd = #{pwd,jdbcType=VARCHAR}
where resource_id = #{resourceId,jdbcType=VARCHAR}
</update>
......
package io.dataease.controller.panel.api;
import io.dataease.controller.request.panel.link.EnablePwdRequest;
import io.dataease.controller.request.panel.link.LinkRequest;
import io.dataease.controller.request.panel.link.PasswordRequest;
import io.dataease.controller.request.panel.link.ValidateRequest;
import io.dataease.dto.panel.link.GenerateDto;
import io.dataease.dto.panel.link.ValidateDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@Api(tags = "仪表板:链接管理")
@RequestMapping("/api/link")
public interface LinkApi {
@ApiOperation("设置密码")
@PostMapping("/replacePwd")
@ApiOperation("重制密码")
@PostMapping("/resetPwd")
void replacePwd(PasswordRequest request);
@ApiOperation("生成")
@PostMapping("/generate")
void generateLink(LinkRequest request);
@ApiOperation("启用密码")
@PostMapping("/enablePwd")
void enablePwd(EnablePwdRequest request);
@ApiOperation("切换开关")
@PostMapping("/switchLink")
void switchLink(LinkRequest request);
@ApiOperation("当前链接信息")
@PostMapping("/currentGenerate/{resourceId}")
GenerateDto currentGenerate(String resourceId);
@ApiOperation("验证访问")
@PostMapping("/validate")
ValidateDto validate(Map<String, String> param);
@ApiOperation("验证密码")
@PostMapping("/validatePwd")
boolean validatePwd(PasswordRequest request);
}
package io.dataease.controller.panel.server;
import com.google.gson.Gson;
import io.dataease.base.domain.PanelLink;
import io.dataease.commons.utils.ServletUtils;
import io.dataease.controller.panel.api.LinkApi;
import io.dataease.controller.request.panel.link.EnablePwdRequest;
import io.dataease.controller.request.panel.link.LinkRequest;
import io.dataease.controller.request.panel.link.PasswordRequest;
import io.dataease.controller.request.panel.link.ValidateRequest;
import io.dataease.dto.panel.link.GenerateDto;
import io.dataease.dto.panel.link.ValidateDto;
import io.dataease.service.panel.PanelLinkService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
public class LinkServer implements LinkApi {
......@@ -33,8 +34,47 @@ public class LinkServer implements LinkApi {
}
@Override
public void generateLink(@RequestBody LinkRequest request) {
panelLinkService.generator(request);
public void enablePwd(@RequestBody EnablePwdRequest request) {
panelLinkService.changeEnablePwd(request);
}
@Override
public void switchLink(@RequestBody LinkRequest request) {
panelLinkService.changeValid(request);
}
@Override
public GenerateDto currentGenerate(@PathVariable("resourceId") String resourceId) {
return panelLinkService.currentGenerate(resourceId);
}
@Override
public ValidateDto validate(@RequestBody Map<String, String> param) {
String link = param.get("link");
String json = null;
try {
json = panelLinkService.decryptParam(link);
} catch (Exception e) {
e.printStackTrace();
}
Gson gson = new Gson();
ValidateRequest request = gson.fromJson(json, ValidateRequest.class);
ValidateDto dto = new ValidateDto();
String resourceId = request.getResourceId();
PanelLink one = panelLinkService.findOne(resourceId);
if (ObjectUtils.isEmpty(one)){
dto.setValid(false);
return dto;
}
dto.setValid(one.getValid());
dto.setEnablePwd(one.getEnablePwd());
dto.setPassPwd(panelLinkService.validateHeads(one));
return dto;
}
@Override
public boolean validatePwd(@RequestBody PasswordRequest request) {
return panelLinkService.validatePwd(request);
}
}
package io.dataease.controller.request.panel.link;
import lombok.Data;
@Data
public class EnablePwdRequest {
private String resourceId;
private boolean enablePwd;
}
......@@ -7,9 +7,5 @@ public class LinkRequest {
private String resourceId;
private String password;
private Boolean enablePwd;
private String uri;
private boolean valid;
}
package io.dataease.controller.request.panel.link;
import lombok.Data;
@Data
public class ValidateRequest {
private String resourceId;
private Long time;
private String salt;
}
package io.dataease.dto.panel.link;
import lombok.Data;
@Data
public class GenerateDto {
private boolean valid;
private boolean enablePwd;
private String uri;
private String pwd;
}
package io.dataease.dto.panel.link;
import lombok.Data;
@Data
public class ValidateDto {
private boolean valid;
private boolean enablePwd;
private boolean passPwd;
}
package io.dataease.service.panel;
import com.google.gson.Gson;
import io.dataease.auth.config.RsaProperties;
import io.dataease.auth.util.JWTUtils;
import io.dataease.auth.util.RsaUtil;
import io.dataease.base.domain.PanelLink;
import io.dataease.base.mapper.PanelLinkMapper;
import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.utils.ServletUtils;
import io.dataease.controller.request.panel.link.EnablePwdRequest;
import io.dataease.controller.request.panel.link.LinkRequest;
import io.dataease.controller.request.panel.link.PasswordRequest;
import io.dataease.dto.panel.link.GenerateDto;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
@Service
public class PanelLinkService {
@Value("${public-link-url:http://localhost:8081/link?link=}")
private String baseUrl;
@Value("${public-link-salt:DataEaseLinkSalt}")
private String salt;
@Resource
private PanelLinkMapper mapper;
public void generator(LinkRequest request){
String resourceId = request.getResourceId();
PanelLink panelLink = mapper.selectByPrimaryKey(resourceId);
public void changeValid(LinkRequest request){
PanelLink po = new PanelLink();
po.setResourceId(resourceId);
po.setEnablePwd(request.getEnablePwd());
po.setPwd(request.getPassword());
if (ObjectUtils.isEmpty(panelLink)){
mapper.insert(po);
}else{
mapper.updateByPrimaryKey(po);
}
po.setResourceId(request.getResourceId());
po.setValid(request.isValid());
mapper.updateByPrimaryKeySelective(po);
}
public void changeEnablePwd(EnablePwdRequest request){
PanelLink po = new PanelLink();
po.setResourceId(request.getResourceId());
po.setEnablePwd(request.isEnablePwd());
mapper.updateByPrimaryKeySelective(po);
}
public void password(PasswordRequest request){
......@@ -40,7 +60,80 @@ public class PanelLinkService {
return panelLink;
}
public GenerateDto currentGenerate(String resourceId) {
PanelLink one = findOne(resourceId);
if (ObjectUtils.isEmpty(one)) {
one = new PanelLink();
one.setPwd(null);
one.setResourceId(resourceId);
one.setValid(false);
one.setEnablePwd(false);
mapper.insert(one);
}
return convertDto(one);
}
public String decryptParam(String text) throws Exception {
return RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, text);
}
// 使用共钥加密
private String encrypt(String sourceValue) {
try {
return RsaUtil.encryptByPublicKey(RsaProperties.publicKey, sourceValue);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String buildLinkParam(String resourceId){
Map<String,Object> map = new HashMap<>();
map.put("resourceId", resourceId);
map.put("time", System.currentTimeMillis());
map.put("salt", salt);
Gson gson = new Gson();
String encrypt = encrypt(gson.toJson(map));
String s = null;
try {
s = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, encrypt);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(s);
return encrypt;
}
private GenerateDto convertDto(PanelLink linl){
GenerateDto result = new GenerateDto();
result.setValid(linl.getValid());
result.setEnablePwd(linl.getEnablePwd());
result.setPwd(linl.getPwd());
result.setUri(baseUrl+buildLinkParam(linl.getResourceId()));
return result;
}
// 验证请求头部携带的信息 如果正确说明通过密码验证 否则没有通过
public Boolean validateHeads(PanelLink panelLink){
HttpServletRequest request = ServletUtils.request();
String token = request.getHeader("LINK-PWD-TOKEN");
if (StringUtils.isEmpty(token)) return false;
boolean verify = JWTUtils.verifyLink(token, panelLink.getResourceId(), panelLink.getPwd());
return verify;
}
public boolean validatePwd(PasswordRequest request) {
String password = request.getPassword();
String resourceId = request.getResourceId();
PanelLink one = findOne(resourceId);
String pwd = one.getPwd();
boolean pass = StringUtils.equals(pwd, password);
if (pass){
String token = JWTUtils.signLink(resourceId, password);
HttpServletResponse httpServletResponse = ServletUtils.response();
httpServletResponse.addHeader("Access-Control-Expose-Headers", "LINK-PWD-TOKEN");
httpServletResponse.setHeader("LINK-PWD-TOKEN", token);
}
return pass;
}
}
......@@ -52,6 +52,7 @@ management.endpoints.web.exposure.include=*
#spring.freemarker.checkTemplateLocation=false
#RSA非对称加密参数:私钥
rsa.private_key=MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
rsa.public_key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ==
spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:/ehcache/ehcache.xml
#打印URL路径
......@@ -60,7 +61,6 @@ logging.level.org.springframework.boot.web=trace
spring.mvc.log-request-details=true
pagehelper.PageRowBounds=true
front-url=http://localhost:9528
......
......@@ -139,6 +139,7 @@ SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE IF EXISTS `panel_link`;
CREATE TABLE `panel_link` (
`resource_id` varchar(50) NOT NULL COMMENT '资源ID',
`valid` tinyint(1) default 0 COMMENT '启用链接',
`enable_pwd` tinyint(1) default 0 COMMENT '启用密码',
`pwd` varchar(255) DEFAULT NULL COMMENT '密码',
PRIMARY KEY (`resource_id`)
......
import request from '@/utils/request'
export function validate(param) {
export function validate(data) {
return request({
url: 'api/link/validate',
method: 'post',
loading: true,
param
data
})
}
export function generate(param) {
export function validatePwd(data) {
return request({
url: 'api/link/generate',
url: 'api/link/validatePwd',
method: 'post',
param
data
})
}
export function setPwd(data) {
return request({
url: 'api/link/resetPwd',
method: 'post',
data
})
}
export function switchValid(data) {
return request({
url: 'api/link/switchLink',
method: 'post',
data
})
}
export function switchEnablePwd(data) {
return request({
url: 'api/link/enablePwd',
method: 'post',
data
})
}
export function loadGenerate(resourceId) {
return request({
url: 'api/link/currentGenerate/' + resourceId,
method: 'post'
})
}
import Vue from 'vue'
import Link from './Link.vue'
import router from './link-router'
import '@/styles/index.scss' // global css
import i18n from '../lang' // internationalization
import ElementUI from 'element-ui'
Vue.config.productionTip = false
Vue.use(ElementUI, {
i18n: (key, value) => i18n.t(key, value)
})
new Vue({
router,
render: h => h(Link)
......
module.exports = {
TokenKey: 'Authorization',
RefreshTokenKey: 'refreshauthorization',
LinkTokenKey: 'LINK-PWD-TOKEN',
title: 'DATA_EASE',
/**
......
......@@ -17,6 +17,7 @@ const getters = {
table: state => state.dataset.table,
loadingMap: state => state.request.loadingMap,
currentPath: state => state.permission.currentPath,
permissions: state => state.user.permissions
permissions: state => state.user.permissions,
linkToken: state => state.link.linkToken
}
export default getters
......@@ -9,7 +9,7 @@ import dataset from './modules/dataset'
import chart from './modules/chart'
import request from './modules/request'
import panel from './modules/panel'
import link from './modules/link'
import animation from './animation'
import compose from './compose'
import contextmenu from './contextmenu'
......@@ -112,7 +112,8 @@ const data = {
dataset,
chart,
request,
panel
panel,
link
},
getters
}
......
const state = {
linkToken: null
}
const mutations = {
SET_LINK_TOKEN: (state, value) => {
state.linkToken = value
}
}
const actions = {
setLinkToken({ commit }, data) {
commit('SET_LINK_TOKEN', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
......@@ -122,3 +122,11 @@ div:focus {
padding: 10px;
}
}
.real-input {
.el-input__inner {
height: 25px !important;
border: none !important;
}
}
......@@ -10,6 +10,7 @@ import { tryShowLoading, tryHideLoading } from './loading'
const TokenKey = Config.TokenKey
const RefreshTokenKey = Config.RefreshTokenKey
const LinkTokenKey = Config.LinkTokenKey
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
......@@ -28,6 +29,9 @@ service.interceptors.request.use(
// please modify it according to the actual situation
config.headers[TokenKey] = getToken()
}
if (store.getters.linkToken) {
config.headers[LinkTokenKey] = store.getters.linkToken
}
// 增加loading
config.loading && tryShowLoading(store.getters.currentPath)
......@@ -68,6 +72,11 @@ const checkAuth = response => {
const refreshToken = response.headers[RefreshTokenKey]
store.dispatch('user/refreshToken', refreshToken)
}
if (response.headers[LinkTokenKey]) {
const linkToken = response.headers[LinkTokenKey]
store.dispatch('link/setLinkToken', linkToken)
}
}
const checkPermission = response => {
......
......@@ -8,6 +8,7 @@
style="width: 370px;"
:active-value="true"
:inactive-value="false"
@change="onChange"
/>
</el-form-item>
<el-form-item label=" ">
......@@ -22,10 +23,10 @@
</el-form-item>
<el-form-item v-if="valid" label=" ">
<el-checkbox v-model="form.enablePwd">密码保护</el-checkbox>
<el-checkbox v-model="form.enablePwd" @change="resetEnablePwd">密码保护</el-checkbox>
<span v-if="form.enablePwd" class="de-span">{{ form.pwd }}</span>
<span v-if="form.enablePwd" class="de-span"><el-link :underline="false" type="primary">重置</el-link></span>
<span v-if="form.enablePwd" class="de-span" @click="resetPwd"><el-link :underline="false" type="primary">重置</el-link></span>
</el-form-item>
<div v-if="valid" class="auth-root-class">
......@@ -41,6 +42,10 @@
</div>
</template>
<script>
import { loadGenerate, setPwd, switchValid, switchEnablePwd } from '@/api/link'
import { encrypt, decrypt } from '@/utils/rsaEncrypt'
export default {
name: 'LinkGenerate',
......@@ -55,20 +60,75 @@ export default {
},
data() {
return {
pwdNums: 4,
valid: false,
form: {},
defaultForm: { enablePwd: false, pwd: '000000', uri: 'http://baidu.com' }
defaultForm: { enablePwd: false, pwd: null, uri: null }
}
},
created() {
this.form = this.defaultForm
this.currentGenerate()
},
methods: {
currentGenerate() {
loadGenerate(this.resourceId).then(res => {
const { valid, enablePwd, pwd, uri } = res.data
this.valid = valid
this.form.enablePwd = enablePwd
this.form.uri = uri
// 返回的密码是共钥加密后的 所以展示需要私钥解密一波
pwd && (this.form.pwd = decrypt(pwd))
})
},
createPwd() {
const randomNum = () => {
return Math.floor(Math.random() * 10) + ''
}
let result = ''
for (let index = 0; index < this.pwdNums; index++) {
result += randomNum()
}
return result
},
resetPwd() {
// 密码采用RSA共钥加密
const newPwd = this.createPwd()
const param = {
resourceId: this.resourceId,
password: encrypt(newPwd)
}
setPwd(param).then(res => {
this.form.pwd = newPwd
})
},
resetEnablePwd(value) {
const param = {
resourceId: this.resourceId,
enablePwd: value
}
switchEnablePwd(param).then(res => {
// 当切换到启用密码保护 如果没有密码 要生成密码
value && !this.form.pwd && this.resetPwd()
})
},
onCopy(e) {
// alert('You just copied: ' + e.text)
},
onError(e) {
// alert('Failed to copy texts')
},
onChange(value) {
const param = {
resourceId: this.resourceId,
valid: value
}
switchValid(param).then(res => {
})
}
}
}
......
<template>
<div>
<link-error v-if="showIndex===0" />
<link-pwd v-if="showIndex===1" />
<link-pwd v-if="showIndex===1" :resource-id="resourceId" />
<link-view v-if="showIndex===2" />
</div>
</template>
......@@ -29,24 +29,23 @@ export default {
loadInit() {
this.link = getQueryVariable(this.PARAMKEY)
validate(this.buildParam()).then(res => {
validate({ link: this.link }).then(res => {
const { valid, enablePwd, passPwd } = res.data
// 如果链接无效 直接显示无效页面
!valid && this.showError()
if (!valid) {
this.showError()
return
}
// 如果未启用密码 直接显示视图页面
!enablePwd && this.showView()
// 如果启用密码 但是未通过密码验证 显示密码框
!passPwd && this.showPwd()
if (enablePwd && !passPwd) {
this.showPwd()
return
}
this.showView()
})
console.log(this.link)
},
buildParam() {
return {}
},
// 显示无效链接
showError() {
this.showIndex = 0
......
<template>
<div>
我是密码页面
<div class="pwd-body">
<div class="pwd-wrapper">
<div class="pwd-content">
<div class="span-header">
<div class="bi-text">
请输入密码打开链接
</div>
</div>
<div class="input-layout">
<div class="input-main">
<div class="div-input">
<el-input v-model="pwd" class="real-input" />
</div>
</div>
<div class="abs-input">
<div class="input-text">{{ msg }}</div>
</div>
</div>
<div class="auth-root-class">
<span slot="footer">
<el-button size="mini" type="primary" @click="validatePwd">确定</el-button>
</span>
</div>
</div>
</div>
</div>
</template>
<script>
import { validatePwd } from '@/api/link'
export default {
name: 'LinkPwd',
props: {
resourceId: {
type: String,
default: null
}
},
data() {
return {
pwd: null,
msg: null
}
},
methods: {
// 验证密码是否正确 如果正确 设置请求头部带LINK-PWD-TOKEN=entrypt(pwd)再刷新页面
refresh() {
validatePwd({ password: this.pwd, resourceId: this.resourceId }).then(res => {
if (!res.data) {
this.msg = '密码错误'
} else {
window.location.reload()
}
})
}
}
}
</script>
<style lang="scss" scoped>
.pwd-body {
position: absolute;
width: 100%;
margin: 0;
padding: 0;
top: 0;
left: 0;
background-repeat: repeat;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
color: #3d4d66;
font: normal 12px Helvetica Neue,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Heiti,黑体,sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-decoration: none;
-kthml-user-focus: normal;
-moz-user-focus: normal;
-moz-outline: 0 none;
outline: 0 none;
height: 100%;
display: block;
}
.pwd-wrapper {
background-color: #F7F8FA;
height: 100%;
justify-content: center !important;
align-items: center !important;
min-height: 25px;
display: flex;
-moz-flex-direction: row;
-o-flex-direction: row;
flex-direction: row;
-moz-justify-content: flex-start;
-ms-justify-content: flex-start;
-o-justify-content: flex-start;
justify-content: flex-start;
-moz-align-items: flex-start;
-ms-align-items: flex-start;
-o-align-items: flex-start;
align-items: flex-start;
-o-flex-wrap: nowrap;
flex-wrap: nowrap;
}
.pwd-content {
width: 450px;
height: 250px;
position: relative;
flex-shrink: 0;
background-color: #FFFFFF;
display: block;
}
.span-header {
position: relative;
margin: 57px auto 0px;
justify-content: center !important;
align-items: center !important;
}
.bi-text {
max-width: 100%;
text-align: center;
white-space: pre;
text-overflow: ellipsis;
position: relative;
flex-shrink: 0;
box-sizing: border-box;
overflow: hidden;
overflow-x: hidden;
overflow-y: hidden;
word-break: break-all;
display: block;
}
.input-layout{
width: 152px;
position: relative;
margin: 0px auto;
padding: 0;
display: block;
}
.input-main {
width: 150px;
height: 30px;
position: relative;
margin-top: 30px;
border: 1px solid #e8eaed;
display: block;
}
.div-input {
inset: 2px 4px;
position: absolute;
display: block;
}
.abs-input {
height: 20px;
position: relative;
margin-top: 5px;
display: block;
}
.input-text {
height: 20px;
line-height: 20px;
text-align: center;
white-space: pre;
text-overflow: ellipsis;
left: 0px;
top: 0px;
bottom: 0px;
position: absolute;
color: #E65251;
box-sizing: border-box;
}
.real-input {
width: 100%;
height: 100%;
border: none;
outline: none;
padding: 0px;
margin: 0px;
inset: 0px;
position: absolute;
display: block;
}
.auth-root-class {
margin: 15px 0px 5px;
text-align: center;
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论