使用jwt方式的接口访问

要使用jwt必须有相应jar包

maven项目加入依赖

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>

普通web项目  将

java-jwt-3.4.0.jar

导入即可

说一下jwt的作用。可以使服务端和客户端之间的信息传递是无状态的。

进入正题:

1.准备好注解类



import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 免验证注解
 * @author 少时诵诗书
 *
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
	 boolean required() default true;
}

这个注解是在登录和注册等不需要验证token的时候在接口方法加的



import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * token验证
 * @author 少时诵诗书
 *
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
	boolean required() default true;
}

这个注解是需要验证token信息

注解解析:从上面我们新建的两个类上我们可以看到主要的等学习到的就四点

第一:如何创建一个注解

第二:在我们自定义注解上新增@Target注解(注解解释:这个注解标注我们定义的注解是可以作用在类上还是方法上还是属性上面)

第三:在我们自定义注解上新增@Retention注解(注解解释:作用是定义被它所注解的注解保留多久,一共有三种策略,SOURCE 被编译器忽略,CLASS  注解将会被保留在Class文件中,但在运行时并不会被VM保留。这是默认行为,所有没有用Retention注解的注解,都会采用这种策略。RUNTIME  保留至运行时。所以我们可以通过反射去获取注解信息。

第四:boolean required() default true;  默认required() 属性为true

2.准备拦截器验证token

在spring-mvc.xml里面配置

    <mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="${adminPath}/**" />
			<mvc:exclude-mapping path="${adminPath}/"/>
			<mvc:exclude-mapping path="${adminPath}/login"/>
			<mvc:exclude-mapping path="${adminPath}/sys/menu/tree"/>
			<mvc:exclude-mapping path="${adminPath}/sys/menu/treeData"/>
			<mvc:exclude-mapping path="${adminPath}/oa/oaNotify/self/count"/>
			<bean class="com.xxx.modules.sys.interceptor.LogInterceptor" />
		</mvc:interceptor>
		<!-- 接口token验证 -->
		<mvc:interceptor>
			<mvc:mapping path="${frontPath}/**" />
			<bean class="com.xxx.modules.sys.interceptor.TokenIntercetor" />
		</mvc:interceptor>
		<!-- 手机视图拦截器 -->
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean class="com.xxx.modules.sys.interceptor.MobileInterceptor" />
		</mvc:interceptor>
	</mvc:interceptors>

拦截器类



import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.jeeplus.modules.sys.annotation.PassToken;
import com.jeeplus.modules.sys.annotation.UserLoginToken;
import com.jeeplus.modules.sys.service.TokenService;

public class TokenIntercetor implements HandlerInterceptor{
	@Autowired
	private TokenService tokenService;

	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
		//取出token
		String token=httpServletRequest.getHeader("token");
		System.out.println(token);
		//如果不是映射方法直接返回
		if(!(object instanceof HandlerMethod)){
			return true;
		}
		HandlerMethod handlermethod=(HandlerMethod)object;
		Method method=handlermethod.getMethod();
		//如果方法注解了passtoken直接跳过
		if(method.isAnnotationPresent(PassToken.class)){
			PassToken passToken=method.getAnnotation(PassToken.class);
			if(passToken.required()){
				return true;
			}
		}
		//如果注解了userLoginToken需要验证
		if(method.isAnnotationPresent(UserLoginToken.class)){
			UserLoginToken userLoginToken=method.getAnnotation(UserLoginToken.class);
			//验证
			if(userLoginToken.required()){
				if(token==null){
					throw new RuntimeException("无token信息,请重新登录");
				}
				//获取token 信息中userid
				String userid;
				try {
					userid=JWT.decode(token).getAudience().get(0);
				} catch (JWTDecodeException e) {
					throw new RuntimeException("401");
				}
				//查询用户是否存在
				if(!userid.equals("123")){//测试用123代替
					throw new RuntimeException("没有该用户");
				}
				//验证密码是否正确
				JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256("456")).build();
				try {
					jwtVerifier.verify(token);
				} catch (JWTVerificationException e) {
					throw new RuntimeException("401");
				}
				return true;
			}
		}
		return false;
	}

}

3.准备一个生成token的工具类或者service



import org.springframework.stereotype.Service;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
/**
 * 生成token的业务层
 * @author 少时诵诗书
 *
 */
@Service
public class TokenService {
	public  String getToken(String userid,String password){
		String token="";
		token=JWT.create().withAudience(userid).sign(Algorithm.HMAC256(password));
		System.out.println(token);
		return token;
	}
	
}

5.测试

准备一个登录接口和获取用户信息的接口



import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jeeplus.common.web.BaseController;
import com.jeeplus.modules.sys.annotation.PassToken;
import com.jeeplus.modules.sys.annotation.UserLoginToken;
import com.jeeplus.modules.sys.service.TokenService;


@Controller
@RequestMapping("${frontPath}")
public class TestController extends BaseController{
	@Autowired
	private TokenService tokenService;
	/**
	 * 登录
	 * @return
	 */
	@RequestMapping("login")
	@ResponseBody
	@PassToken
	public HashMap<String, Object> login(){
		HashMap<String, Object> m=new HashMap<String, Object>();
		String token="";
		token=tokenService.getToken("123", "456");
	    m.put("status", 200);
		m.put("token", token);
		return m;
	}
	
	@RequestMapping("getUserInfo")
	@ResponseBody
	@UserLoginToken
	public String getUserInfo(){
		return "用户信息以获取";
	}
}

用postman测试、

登录并获取token

测试请求不加token的访问

服务器抛出异常

加上token的访问

可以了。

以上就是使用jwt方式的接口访问

猜你喜欢

转载自blog.csdn.net/menxinziwen/article/details/89047484