Java 手机Web开发 身份验证

来源:互联网 发布:手机钢琴软件哪个好 编辑:程序博客网 时间:2024/06/05 18:23

Java web和手机端开发 遇到比较麻烦的就是身份验证

目前为止觉得最好的解决方案是 Java 中使用jwt 

为什么要使用jwt,让网络数据更加安全,以防其他一些人无意恶搞
在这里简单说下:jwt是一个开源的java库,一个自包含的Java库,提供终端到终端的JSON网络令牌的创建和验证。
JWT的目标是成为最简单的库,用于创建和JVM上的验证JSON网络令牌(JWTs),

这里采用的框架是nutz框架 数据库mysql  和redis

Jwts 验证需要一个key 但是 KEY默认是存储在内存 如果想长久存储 使用redis以字节流方式 更好

其次 token的获取用redis 更加方便 存储时加一个过期时间 不占用资源


直接看代码

@IocBean(args = {"refer:dao"})public class ApiService extends Service<Sys_api> {    private static final Log log = Logs.get();    public ApiService(Dao dao) {        super(dao);    }    private static final String at="accessToken";    public static Key key;    /**     * 生成token     * Key以字节流形式存入redis     *     * @param date  失效时间     * @param appId AppId     * @return     */    @Aop("redis")    public String generateToken(Date date, String appId){        try{            byte[] buf = jedis().get("api:key".getBytes());            if (buf == null) { // 建新的key                key = MacProvider.generateKey();                ByteArrayOutputStream bao = new ByteArrayOutputStream();                ObjectOutputStream oos = new ObjectOutputStream(bao);                oos.writeObject(key);                buf = bao.toByteArray();                jedis().set("api:key".getBytes(), buf);            } else { // 重用老key                key = (Key) new ObjectInputStream(new ByteArrayInputStream(buf)).readObject();            }        }catch (IOException io){            System.out.println(io);        }catch (ClassNotFoundException c){            System.out.println(c);        }        String token = Jwts.builder()                .setSubject(appId)                .signWith(SignatureAlgorithm.HS512, key)                .setExpiration(date)                .compact();        // 计算失效秒,7889400秒三个月        Date temp = new Date();        long interval = (date.getTime() - temp.getTime())/1000;        jedis().setex(at+appId ,(int)interval,token);        return token;    }    /**     * 验证token     * @param appId AppId     * @param token token     * @return     */    @Aop("redis")    public boolean verifyToken(String appId, String token) {        try {            if (key == null) {                byte[] buf = jedis().get("api:key".getBytes());                if(buf==null){                    return false;                }                key = (Key) new ObjectInputStream(new ByteArrayInputStream(buf)).readObject();            }            Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody().getSubject().equals(appId);            return true;        } catch (Exception e) {            log.debug(e.getMessage());            return false;        }    }    /**     * 获取token     * @param appId     * @return     */    @Aop("redis")    public String getToken(String appId) {        return jedis().get(at+appId);    }    /**     * 验证会员ID,用于首页接口、产品查看、收藏等接口     * @param appId     * @return     */    public boolean verifyId(String appId) {        try {            App_user user = dao().fetch(App_user.class, Cnd.where("id","=",Long.parseLong(appId)));            if (user!=null){                return true;            }else {                return false;            }        } catch (Exception e) {            log.debug(e.getMessage());            return false;        }    }

如果不想用redis存储可以采用文件流的形式

参考代码如下

github地址https://github.com/Wizzercn/NutzWk/blob/7851cfdb8688b30d5843d6a162113cd1d033ccc9/src/main/java/cn/wizzer/modules/services/sys/SysApiService.java#L65

package cn.wizzer.modules.services.sys;import cn.wizzer.common.base.Globals;import cn.wizzer.common.base.Result;import cn.wizzer.common.base.Service;import cn.wizzer.modules.models.sys.Sys_api;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import io.jsonwebtoken.impl.crypto.MacProvider;import org.nutz.dao.Chain;import org.nutz.dao.Cnd;import org.nutz.dao.Dao;import org.nutz.ioc.loader.annotation.IocBean;import org.nutz.json.Json;import org.nutz.lang.Files;import org.nutz.lang.Strings;import org.nutz.log.Log;import org.nutz.log.Logs;import java.io.*;import java.security.Key;import java.util.Date;/** * Created by wizzer on 2016/8/11. */@IocBean(args = {"refer:dao"})public class SysApiService extends Service<Sys_api> {    private static final Log log = Logs.get();    public SysApiService(Dao dao) {        super(dao);    }    public static Key key;    /**     * 生成token     *     * @param date 失效时间     * @param appId  appId     * @return     */    public String generateToken(Date date, String appId) throws IOException, ClassNotFoundException {        File f = new File(Globals.AppRoot + "/WEB-INF/apikey/" + appId + ".key");        if (Files.isFile(f)) {            ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(f));            key = (Key) keyIn.readObject();            keyIn.close();        } else {            key = MacProvider.generateKey();            Files.createNewFile(f);            ObjectOutputStream keyOut = new ObjectOutputStream(new FileOutputStream(f));            keyOut.writeObject(key);            keyOut.close();        }        return Jwts.builder()                .setSubject(appId)                .signWith(SignatureAlgorithm.HS512, key)                .setExpiration(date)                .compact();    }    /**     * 验证token     *     * @param appId AppId     * @param token token     * @return     */    public boolean verifyToken(String appId, String token) {        try {            if (key == null) {                ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(Globals.AppRoot + "/WEB-INF/apikey/" + appId + ".key"));                key = (Key) keyIn.readObject();                keyIn.close();            }            Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody().getSubject().equals(appId);            return true;        } catch (Exception e) {            log.debug(e.getMessage());            return false;        }    }}


0 0