81,122
社区成员




@POST
@Path("/loginUser")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response loginUser(String resquestJsonBody,@Context HttpServletRequest request)
{
logger.info(String.format("Request IP--%s;requestJsonBody--%s", IpUtils.getIpAddr(request), resquestJsonBody));
ZyLoginResponseVo zyLoginResponseVo = new ZyLoginResponseVo();
String jsonRequestStr = RequestUtils.str2Json(resquestJsonBody);
ZyLoginRequestVo zyLoginRequestVo = JSONObject.parseObject(jsonRequestStr, ZyLoginRequestVo.class);
Map<String,Object> loginResult = zyLoginApiService.loginByUserName(zyLoginRequestVo);
int code = Integer.parseInt(String.valueOf(loginResult.get("loginCode")));
if (loginResult.get("loginCode").equals(Constants.AUTH_RESULT_SUCCESS))
{
//查询用户信息
ZyUserDto resultDto= zyLoginApiService.findUserByName(zyLoginRequestVo.getUser_name());
if(null == resultDto){
//用户不存在
zyLoginResponseVo.setCode(code);
zyLoginResponseVo.setDesc("User is not exists!!");
logger.info("The responseJsonObject:" + JSONObject.toJSONString(zyLoginResponseVo));
return Response.status(200).entity(JSONObject.toJSONString(zyLoginResponseVo)).type(new MediaType(CommonStr.APPLICATION, CommonStr.JSON, CommonStr.UTF8)).build();
}
//组装缓存数据
String userName = String.valueOf(loginResult.get("userName"));
String mobilePhone = String.valueOf(loginResult.get("mobilePhone"));
Map<String,Object> claims = new HashMap<String,Object>();
claims.put("acessToken", loginResult.get("accessToken"));
claims.put("companyname", resultDto.getCompanyname());
if(StringUtils.isEmpty(userName)){
claims.put("name", resultDto.getUsername());
}else{
claims.put("name", userName);
}
if(StringUtils.isEmpty(mobilePhone)){
claims.put("phone", resultDto.getPhone());
}else{
claims.put("phone", mobilePhone);
}
claims.put("status", resultDto.getStatus());
claims.put("companykey", resultDto.getCompanykey());
claims.put("companyid", resultDto.getCompanyid());
claims.put("id", resultDto.getId());
// 设置这个token的生命时间
Date expiry = getExpiryDate(30 * 24 * 60);//30天的有效日期
// 使用Token工具类得到token,生成的策略是利用用户的姓名,到期时间,和私钥
// 使用Key key =MacProvider.generateKey(SignatureAlgorithm.HS512);
// HS512签名算法,必须保存生成的这个key到硬盘上,不然下次会出错,因为是hash算法,所以会变
String userToken = TokenUtil.getJWTString(zyLoginRequestVo.getUser_name(), expiry,KeyUtil.getKey(context),resultDto.getCompanyid(),claims);
logger.info("login Success, Token is:" + userToken+"; user is :"+userName);
System.err.println("token is :"+userToken);
zyLoginResponseVo.setCode(code);
zyLoginResponseVo.createInstanceData().setToken(userToken);
zyLoginResponseVo.setDesc("登录成功!");
}else{
String desc = ResultCodeDescUtil.getResultDesc(code);
zyLoginResponseVo.setCode(code);
zyLoginResponseVo.setDesc(desc);
}
logger.info("The responseJsonObject:" + JSONObject.toJSONString(zyLoginResponseVo));
return Response.status(200).entity(JSONObject.toJSONString(zyLoginResponseVo)).type(new MediaType(CommonStr.APPLICATION, CommonStr.JSON, CommonStr.UTF8)).build();
}
package ichano.developer.util;/**
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.security.Key;
import java.util.Date;
import java.util.Map;
import javax.annotation.security.PermitAll;
/**
* @ClassName: TokenUtil
* @Description: TODO(token管理工具类)
* @author lizhijun
* @date 2016年8月11日 下午12:57:44
*
*/
@PermitAll
public class TokenUtil {
public static String getJWTString(String tel,Date expires,Key key,String commpanyId,Map<String,Object> claims){
if (tel == null) {
throw new NullPointerException("null username is illegal");
}
if (expires == null) {
throw new NullPointerException("null expires is illegal");
}
if (key == null) {
throw new NullPointerException("null key is illegal");
}
SignatureAlgorithm signatureAlgorithm =SignatureAlgorithm.HS256;
String jwtString = Jwts.builder()
.setIssuer("Jersey-Security-Basic")
.setSubject(tel)
.setAudience("user")
.setExpiration(expires)
.setClaims(claims)
.setIssuedAt(new Date())
.setId(commpanyId)
.signWith(signatureAlgorithm,key)
.compact();
return jwtString;
}
public static boolean isValid(String token, Key key) {
try {
Jwts.parser().setSigningKey(key).parseClaimsJws(token.trim());
return true;
} catch (Exception e) {
return false;
}
}
public static String getName(String jwsToken, Key key) {
if (isValid(jwsToken, key)) {
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);
String name = String.valueOf(claimsJws.getBody().get("name"));
return name;
}
return null;
}
public static String[] getRoles(String jwsToken, Key key) {
if (isValid(jwsToken, key)) {
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);
return claimsJws.getBody().getAudience().split(",");
}
return new String[]{};
}
public static int getVersion(String jwsToken, Key key) {
if (isValid(jwsToken, key)) {
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);
return Integer.parseInt(claimsJws.getBody().getId());
}
return -1;
}
/**
* @Title: getCompanyId
* @Description: TODO(获取企业ID)
* @param @param jwsToken
* @param @param key
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String getCompanyId(String jwsToken, Key key) {
if (isValid(jwsToken, key)) {
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);
String companyid = String.valueOf(claimsJws.getBody().get("id"));
return companyid;
}
return null;
}
/**
* @Title: setAcccessToken
* @Description: TODO(存放鉴权中心token)
* @param @param accessToken
* @param @param key
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static void setAcccessToken(String authToken, Key key,String accessToken) {
if (isValid(authToken, key)) {
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(authToken);
claimsJws.getBody().put("acessToken", accessToken);
}
}
/**
* @Title: getCompanyId
* @Description: TODO(获取鉴权中心Token)
* @param @param jwsToken
* @param @param key
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String getAccessToken(String jwsToken, Key key) {
if (isValid(jwsToken, key)) {
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);
return claimsJws.getBody().getSubject();
}
return null;
}
}
<div class="header" style="background-color:#14C2FF;width:400px,height:800px; border:1px red solid;">
<form action="http://localhost:8080/ichanoDeveloper/product/uploadProductImg" method="post" enctype="multipart/form-data">
<p>
<input type="file" class="sys_input" name ="productLogo" id="productLogo" />
剩productId:<input type="text" name="productId" value="20" id="productId"/><br />
</p>
<input type="submit" value="上传" />
</form>
</div>
(二)处理代码
/**
* @Title: uploadFileCheck
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param @param fileInputStream
* @param @param disposition
* @param @param request
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
@POST
@Path("/uploadFileCheck")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
public Response uploadTemp( @FormDataParam("updateLicense") final InputStream uploadedInputStream,
@FormDataParam("updateLicense") final FormDataContentDisposition fileDetail,
@FormDataParam( "surplusCount") final List<FormDataBodyPart> keywordObjs,@Context HttpServletRequest request ) {
String fileName = Calendar.getInstance().getTimeInMillis()+ fileDetail.getFileName();
ZyUploadLicenseFileResponseVo zyUploadLicenseFileResponseVo = new ZyUploadLicenseFileResponseVo();
ZyUploadLicenseFileRequestVo zyUploadLicenseFileRequestVo = new ZyUploadLicenseFileRequestVo();
if (keywordObjs != null && ! keywordObjs.isEmpty()) {
for (FormDataBodyPart keywordObj : keywordObjs) {
String keyName = keywordObj.getName();
if("surplusCount".equals(keyName)){
zyUploadLicenseFileRequestVo.setSurplusCount(keywordObj.getValueAs(String.class));
break;
}
}
}
String accessToken = TokenUtil.getAccessToken(request.getHeader("auth_token"),KeyUtil.getKey(context));
Key key= KeyUtil.getKey(context);
if (TokenUtil.isValid(accessToken,key)){
zyUploadLicenseFileRequestVo.setInputStream(uploadedInputStream);
zyUploadLicenseFileRequestVo.setFileName(fileName);
zyUploadLicenseFileResponseVo= zyLicenseApiService.uploadBatchExcel(zyUploadLicenseFileRequestVo);
}else{
zyUploadLicenseFileResponseVo.setCode(Constants.AUTH_RESULT_FILE_SESSIONOUT);
zyUploadLicenseFileResponseVo.setDesc("Session is out!");
}
logger.info("The responseJsonObject:" + JSONObject.toJSONString(zyUploadLicenseFileResponseVo));
return Response.status(200).entity(JSONObject.toJSONString(zyUploadLicenseFileResponseVo)).type(new MediaType(CommonStr.APPLICATION, CommonStr.JSON, CommonStr.UTF8)).build();
}
@Override
public ZyUploadLicenseFileResponseVo uploadBatchExcel(ZyUploadLicenseFileRequestVo zyUploadLicenseFileRequestVo) {
ZyUploadLicenseFileResponseVo zyUploadLicenseFileResponseVo = new ZyUploadLicenseFileResponseVo();
// 参数有误
if (!zyUploadLicenseFileRequestVo.isValid()) {
logger.error("The argument is null!");
zyUploadLicenseFileResponseVo.setCode(Constants.AUTH_RESULT_FILE_2001);
zyUploadLicenseFileResponseVo.setDesc("The argument is invalid!!");
return zyUploadLicenseFileResponseVo;
}
String fileName = zyUploadLicenseFileRequestVo.getFileName();
List licenseInfo = new ArrayList<String>();
if(!fileName.contains("xls")){
logger.error("The fileName[{}] is error!", fileName);
zyUploadLicenseFileResponseVo.setCode(Constants.UPLOAD_FAILE_9002);
zyUploadLicenseFileResponseVo.setDesc("The file fomart is faile!!");
return zyUploadLicenseFileResponseVo;
}
try {
workbook = new XSSFWorkbook(zyUploadLicenseFileRequestVo.getInputStream());
XSSFSheet sheet = workbook.getSheetAt(0); //获取第一个sheet
int rows = sheet.getPhysicalNumberOfRows();//行数
int cols = sheet.getRow(1).getPhysicalNumberOfCells();//列数
if(cols != 2){
logger.error("The file fomart is faile!");
zyUploadLicenseFileResponseVo.setCode(Constants.UPLOAD_FAILE_9002);
zyUploadLicenseFileResponseVo.setDesc("文件格式错误!!");
return zyUploadLicenseFileResponseVo;
}
//校验上传的excel是否为标准模版
if(rows>0){
//有数据
for(int i=3;i<rows;i++){
//从第四行开始检索
String tempLicense = String.valueOf(sheet.getRow(i).getCell(1));
if(tempLicense.length()<=32){
licenseInfo.add(tempLicense);
}
}
}
int surplusLicenseInt = Integer.parseInt(zyUploadLicenseFileRequestVo.getSurplusCount());
zyUploadLicenseFileResponseVo.setCode(Constants.AUTH_RESULT_SUCCESS);
zyUploadLicenseFileResponseVo.setDesc("Upload File Success!");
zyUploadLicenseFileResponseVo.createInstanceData().setLicenseList(licenseInfo);
return zyUploadLicenseFileResponseVo;
} catch (IOException e) {
e.printStackTrace();
logger.error("解析上传文件失败!");
zyUploadLicenseFileResponseVo.setCode(Constants.UPLOAD_FAILE_9002);
zyUploadLicenseFileResponseVo.setDesc("解析上传文件失败!");
return zyUploadLicenseFileResponseVo;
}
}
好,至此,项目已经可以跑起来。但是还没有进行集群部署,后面还要进行测试。有问题我会继续补上。
参考文献:
http://blog.csdn.net/li563868273/article/details/50277359
http://www.open-open.com/lib/view/open1433995002942.html
http://www.tuicool.com/articles/ZvA36nz
package ichano.developer.sys.filter;/**
import ichano.developer.biz.service.ZyLoginService;
import ichano.developer.dto.ZyUserDto;
import ichano.developer.util.KeyUtil;
import ichano.developer.util.TokenUtil;
import java.io.IOException;
import java.security.Key;
import javax.annotation.Priority;
import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.ws.rs.Priorities;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.glassfish.jersey.server.ContainerRequest;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @ClassName: JWTSecurityFilter
* @Description: TODO(权限验证过滤器)
* @author lizhijun
* @date 2016年8月11日 下午1:18:52
*
*/
@Provider
@Priority(Priorities.AUTHENTICATION)//优先级最高
//实现该拦截器借口
//@Provider可以自动注册
@PreMatching //这个必须添加,否则无法拦截请求
public class JWTSecurityFilter implements ContainerRequestFilter{
final static Logger logger = LogManager.getLogger(JWTSecurityFilter.class.getName());
@Autowired
ZyLoginService zyLoginService;
@Context
ServletContext context;
@Inject
javax.inject.Provider<UriInfo> uriInfo;
public static String extractJwtTokenFromAuthorizationHeader(String auth) {
//Replacing "Bearer Token" to "Token" directly
return auth.replaceFirst("[B|b][E|e][A|a][R|r][E|e][R|r] ", "").replace(" ", "");
}
//重写验证过滤器
@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
//获取本地的私钥
Key key= KeyUtil.getKey(context);
//得到访问的方法 例如GET,POST
String method = containerRequestContext.getMethod().toLowerCase();
//预校验请求处理
if(method.equals("options")){
containerRequestContext.setSecurityContext(new SecurityContextAuthorizer(uriInfo,new AuthorPricinple("pass"), new String[]{"pass"}));
return;
}
//得到访问路径
String path = ((ContainerRequest) containerRequestContext).getPath(true).toLowerCase();
System.err.println("authorizationHeader path is :"+path);
//不需要验证,post验证过滤,注册过滤。
if ("post".equals(method) && "developer/loginuser".equals(path)
|| "developer/registeruser".equals(path)
|| "developer/sendverifcode".equals(path)
|| "developer/updatepwd".equals(path)
||"license/uploadfilecheck".equals(path)
||"product/uploadproductimg".equals(path)) {
containerRequestContext.setSecurityContext(new SecurityContextAuthorizer(uriInfo,new AuthorPricinple("pass"), new String[]{"pass"}));
return;
}
//获取头信息中的token
MultivaluedMap<String, String> testToken = ((ContainerRequest) containerRequestContext).getHeaders();
String authorizationHeader = ((ContainerRequest) containerRequestContext).getHeaderString("auth_token");
//如果token为空抛出
if (authorizationHeader == null) {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);//抛出未认证的错误
}
//把Bear Token换成Token
String strToken=extractJwtTokenFromAuthorizationHeader(authorizationHeader);
if (TokenUtil.isValid(strToken,key)){
String name=TokenUtil.getName(strToken,key);//反解出Name
// String[] roles=TokenUtil.getRoles(strToken,key);//反解出角色
if(name !=null){
ZyUserDto user=zyLoginService.findUserByName(name);
if(user!=null){
containerRequestContext.setSecurityContext(new SecurityContextAuthorizer(uriInfo,new AuthorPricinple(name), new String[]{"user"}));
return;
}
else{
logger.info("User not found " + name);
}
}
else {
logger.info("name, roles or version missing from token");
}
}
else {
logger.info("token is invalid");
}
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}
}
(五)、前端请求代码:
采用ajax post请求方式。
// 发送登陆请求
$.ajax({
url: "http://192.168.0.55:8080/developer/developer/loginUser",
type: "POST",
dataType: "json",
contentType: "application/json", //注意:如果有post data参数的时候,必须加这段,否则请求获取不到参数
data: {
user_name: userName,
password: userPwd,
type: type
},
success: function(data) {
console.log(data);
if (data.code == 1000) {
$.cookie('token', data.data.token);
console.log(1);
parent.location.reload();
} else if (data.code == 2006) {
layer.msg("用户名密码错误");
} else {
layer.msg("登陆异常");
}
}
});
//访问接口请求
$.ajax({
url: "http://192.168.0.181:9102/developer/developer/checkLogin",
type: 'POST',
dataType: 'json',
beforeSend: function(request) { //添加请求响应头中的自定义token
request.setRequestHeader("auth_token", token);
},
success: function(data) {
if (data.code == 1000) {
var html = [];
html.push(Mustache.render(userNameTemp, data.data));
$userNameCon.html(html.join(''));
} else {
window.location.href = "index.html"
}
}
})
二、CORS跨域访问
使用cors进行跨域配置其实很简单,只需要引用jar包,然后添加过滤器即可。但是有些细节还是要注意。
(一)、jar包引用
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.thetransactioncompany/java-property-utils -->
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>java-property-utils</artifactId>
<version>1.9.1</version>
</dependency>
(二)、过滤器实现
web.xml配置:
<filter>
<filter-name>cros</filter-name>
<filter-class>ichano.developer.sys.filter.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cros</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤器中可以配置允许访问的请求方,允许访问的请求方式以及允许通过的请求头信息
package ichano.developer.sys.filter;/**
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* @ClassName: CorsFilter
* @Description: TODO(设置其他IP地址的机器可以直接访问本项目Url--工具filter)
* @author lizhijun
* @date 2016年8月15日 下午2:25:25
*
*/
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*"); //为安全起见,可配置允许访问的请求方地址。这里配置成*号,是允许所有访问。
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); //为安全起见,也可配置成只允许POST请求
response.addHeader("Access-Control-Allow-Headers", "Content-Type,auth_token"); //这里要注意,auth_token是我自定义的请求头当中带的token,在这里必须添加,否则你永远获取不到。
response.addHeader("Access-Control-Max-Age", "1800");//30 min
filterChain.doFilter(request, response);
}
}
这里处理了三个坑,
一是在本地调试的时候可以跨域访问,但是部署到服务器之后,访问失败。解决方法:请求地址后面加上端口号就可以访问。 这个问题就需要在nignx里面进行端口配置。
二是CROS这种传输方式传输的数据到后端接收已不是JSON格式,而是类似于XXX=123&FFFF=384这样的格式,需要对所有请求的入参进行一下转换成json格式。
三是请求头中的自定义字段auth_token在服务器上接收不到,这里需要对ngnix进行配置,允许自定义属性的header配置。
[b]