Java开源生鲜电商平台-Java后端生成Token架构与设计详解(源码可下载)

Java开源生鲜电商平台-Java后端生成Token架构与设计详解(源码可下载)

目的:Java开源生鲜电商平台-Java后端生成Token目的是为了用于校验客户端,防止重复提交.

技术选型:用开源的JWT架构。

1.概述:在web项目中,服务端和前端经常需要交互数据,有的时候由于网络相应慢,客户端在提交某些敏感数据(比如按照正常的业务逻辑,此份数据只能保存一份)时,如果前端多次点击提交按钮会导致提交多份数据,这种情况我们是要防止发生的。

2.解决方法:

①前端处理:在提交之后通过js立即将按钮隐藏或者置为不可用。

②后端处理:对于每次提交到后台的数据必须校验,也就是通过前端携带的令牌(一串唯一字符串)与后端校验来判断当前数据是否有效。

3.总结:第一种方法相对来说比较简单,但是安全系数不高,第二种方法从根本上解决了问题,所以我推荐第二种方法。

4.核心代码:

生成Token的工具类:

  1. /**
  2. * 生成Token的工具类:
  3. */
  4. package red.hearing.eval.modules.token;
  5. import java.security.MessageDigest;
  6. import java.security.NoSuchAlgorithmException;
  7. import java.util.Random;
  8. import sun.misc.BASE64Encoder;
  9. /**
  10. * 生成Token的工具类
  11. * @author zhous
  12. * @since 2018-2-23 13:59:27
  13. *
  14. */
  15. public class TokenProccessor {
  16. private TokenProccessor(){};
  17. private static final TokenProccessor instance = new TokenProccessor();
  18. public static TokenProccessor getInstance() {
  19. return instance;
  20. }
  21. /**
  22. * 生成Token
  23. * @return
  24. */
  25. public String makeToken() {
  26. String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
  27. try {
  28. MessageDigest md = MessageDigest.getInstance("md5");
  29. byte md5[] =  md.digest(token.getBytes());
  30. BASE64Encoder encoder = new BASE64Encoder();
  31. return encoder.encode(md5);
  32. } catch (NoSuchAlgorithmException e) {
  33. // TODO Auto-generated catch block
  34. e.printStackTrace();
  35. }
  36. return null;
  37. }
  38. }

Token通用工具类

  1. /**
  2. *
  3. */
  4. package red.hearing.eval.modules.token;
  5. import javax.servlet.http.HttpServletRequest;
  6. import org.apache.commons.lang3.StringUtils;
  7. /**
  8. * Token的工具类
  9. * @author zhous
  10. * @since 2018-2-23 14:01:41
  11. *
  12. */
  13. public class TokenTools {
  14. /**
  15. * 生成token放入session
  16. * @param request
  17. * @param tokenServerkey
  18. */
  19. public static void createToken(HttpServletRequest request,String tokenServerkey){
  20. String token = TokenProccessor.getInstance().makeToken();
  21. request.getSession().setAttribute(tokenServerkey, token);
  22. }
  23. /**
  24. * 移除token
  25. * @param request
  26. * @param tokenServerkey
  27. */
  28. public static void removeToken(HttpServletRequest request,String tokenServerkey){
  29. request.getSession().removeAttribute(tokenServerkey);
  30. }
  31. /**
  32. * 判断请求参数中的token是否和session中一致
  33. * @param request
  34. * @param tokenClientkey
  35. * @param tokenServerkey
  36. * @return
  37. */
  38. public static boolean judgeTokenIsEqual(HttpServletRequest request,String tokenClientkey,String tokenServerkey){
  39. String token_client = request.getParameter(tokenClientkey);
  40. if(StringUtils.isEmpty(token_client)){
  41. return false;
  42. }
  43. String token_server = (String) request.getSession().getAttribute(tokenServerkey);
  44. if(StringUtils.isEmpty(token_server)){
  45. return false;
  46. }
  47. if(!token_server.equals(token_client)){
  48. return false;
  49. }
  50. return true;
  51. }
  52. }

使用方法:

①在输出前端页面的时候调用TokenTools.createToken方法,会把本次生成的token放入session中。

②然后在前端页面提交数据时从session中获取token,然后添加到要提交的数据中。

③服务端接受数据后调用judgeTokenIsEqual方法判断两个token是否一致,如果不一致则返回,不进行处理。

备注:tokenClientkey和tokenServerkey自定义,调用judgeTokenIsEqual方法时的tokenClientkey一定要与前端页面的key一致。

基于微信原理JAVA实现线程安全Token验证-JWT,如果不清楚JWT TOKEN的原理机制,我的上一篇JWT-TOKEN博客有详细介绍,这篇博文主要是具体实现。

Token主要是用于以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上密匙。

package com.franz.websocket;

import com.franz.common.utils.StringUtils;
import com.franz.weixin.p3.oauth2.util.MD5Util;
import io.jsonwebtoken.*;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.jeecgframework.core.common.service.CommonService;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.DatatypeConverter;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * OAuthTokenUtils
 * Token管理
 * @author [email protected]
 * @version 2017-08-01
 */
public class OAuthTokenManager {
    private String APP_ID = "";
    private String APP_SECRET = "";
    private String KEY_SING =  ""; //用於存放TOKEN的標誌,Redis
    private LinkedHashMap<string, object=""> pairs = new LinkedHashMap();//封装json的map
    private CommonService service;
    public static final int MINUTE_TTL = 60*1000;  //millisecond
    public static final int HOURS_TTL = 60*60*1000;  //millisecond
    public static final int DAY_TTL = 12*60*60*1000;  //millisecond

    private OAuthTokenManager() {}
    private static OAuthTokenManager single=null;
    public static OAuthTokenManager getInstance() {
            if (single == null) {
                single = new OAuthTokenManager();
            }
            return single;
        }

    public String getKEY_SING() {
        return KEY_SING;
    }

    public void setPairs(LinkedHashMap<string, object=""> pairs) {
        this.pairs = pairs;
    }
    public LinkedHashMap<string, object=""> getPairs() {
        return pairs;
    }

    public void put(String key, Object value){//向json中添加属性,在js中访问,请调用data.map.key
        pairs.put(key, value);
    }

    public void remove(String key){
        pairs.remove(key);
    }

    /**
     * 總體封裝
     * @param appid
     * @param secret
     * @param logicInterface 回調函數
     * @return
     */
    public String token(String appid,String secret,LogicInterface logicInterface){
        //获取appid和secret
        this.accessPairs(appid,secret);
        //验证appid和secretS,获取对象载体
        Object subject = this.loginAuthentication(logicInterface);
        //生成JWT签名数据ToKen
        String token = this.createToken(this.generalSubject(subject),this.MINUTE_TTL);
        return token;
    }

    public void accessPairs(String APP_ID, String APP_SECRET) {
        this.APP_ID = APP_ID;
        this.APP_SECRET = APP_SECRET;
        //this.KEY_SING = MD5Util.MD5Encode(APP_ID+"_"+APP_SECRET, "UTF-8").toUpperCase();//要用到的时候才用
    }

    public Object loginAuthentication(LogicInterface logicInterface){
        if (StringUtils.isNotBlank(APP_ID) && StringUtils.isNotBlank(APP_SECRET)) {
                Map<string, object=""> map = new HashMap<>();
                map.put("APP_ID",APP_ID);
                map.put("APP_SECRET",APP_SECRET);
                if(logicInterface == null || logicInterface.handler(map) == null){
                    return map;
                }else {
                    return logicInterface.handler(map);
                }
        } else {
            return null;
        }
    }
    /**
     * 由字符串生成加密key
     * @return
     */
    public SecretKey generalKey(){
        String stringKey = APP_ID+APP_SECRET;
        byte[] encodedKey = Base64.decodeBase64(stringKey);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }
    /**
     * 生成subject信息
     * @param obj
     * @return
     */
    public static String generalSubject(Object obj){
        if(obj != null ) {
            JSONObject json = JSONObject.fromObject(obj);
            return json.toString();
        }else{
            return "{}";
        }

    }

    /**
     * 创建token
     * @param subject
     * @param ttlMillis
     * @return
     * @throws Exception
     */
    public String createToken(String subject, long ttlMillis) {

        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey key = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setId(APP_ID)
                .setIssuedAt(now)
                .setSubject(subject)
                .signWith(signatureAlgorithm, key);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * 解密token
     * @param token
     * @return
     * @throws Exception
     */
    public Claims validateToken(String token) throws Exception{
        Claims claims = Jwts.parser()
                .setSigningKey(generalKey())
                .parseClaimsJws(token).getBody();
        /*System.out.println("ID: " + claims.getId());
        System.out.println("Subject: " + claims.getSubject());
        System.out.println("Issuer: " + claims.getIssuer());
        System.out.println("Expiration: " + claims.getExpiration());*/
        return claims;
    }
}
import com.ewider.weixin.p3.oauth2.util.MD5Util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * OAuthTokenController
 *
 * @author Franz.ge.倪志耿
 * @version 2017-08-01
 */
@Scope("prototype")
@Controller
@RequestMapping("/oAuthToken")
public class OAuthToken {

    /**
     * 獲取Token
     * @param grant_type
     * @param appid
     * @param secret
     * @return
     */
    @RequestMapping(params = "token",method = RequestMethod.GET)
    @ResponseBody
    public Object token (@RequestParam(value = "grant_type") String grant_type, @RequestParam(value = "appid") String appid,
            @RequestParam(value = "secret") String secret,HttpServletResponse response) {
        Map<string, object=""> map = new HashMap<>();
        switch (grant_type) {
            case "authorization_code" : //授权码模式(即先登录获取code,再获取token)
                break;
            case "password" : //密码模式(将用户名,密码传过去,直接获取token)
                break;
            case "client_credentials" : //客户端模式(无用户,用户向客户端注册,然后客户端以自己的名义向’服务端’获取资源)
                OAuthTokenManager oAuthTokenManager = OAuthTokenManager.getInstance();
                String token = oAuthTokenManager.token(appid, secret,null);//loginInterface是业务逻辑回掉函数
                //返回Token
                map.put("access_token",token);
                map.put("expires_in",OAuthTokenManager.MINUTE_TTL/1000);
                break;
            case "implicit" : //简化模式(在redirect_uri 的Hash传递token; Auth客户端运行在浏览器中,如JS,Flash)
                break;
            case "refresh_token" : //刷新access_token
                break;
        }

        return map;
    }

    @RequestMapping(params = "loginAuth2",method = RequestMethod.GET)
    @ResponseBody
    public Object loginAuth2 (HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "accessToken") String accessToken ){
        Map<string, object=""> map = new HashMap<>();
        //COOKIE不存在:解析验证正确性
        try {
                OAuthTokenManager oAuthTokenManager = OAuthTokenManager.getInstance();
                Claims claims = oAuthTokenManager.validateToken(accessToken);
                if (claims != null ) {
                    map.put("state","success");
                    map.put("loginAuth","采用Token登录");
                    int validMillis = (int)(claims.getExpiration().getTime()-System.currentTimeMillis());
                    if(validMillis > 0) {
                        //交給容器管理,可以存放redis,這裡模擬是cookie
                        Cookie cookie = new Cookie(MD5Util.MD5Encode("MD5SING", "UTF-8").toUpperCase(), accessToken);
                        cookie.setMaxAge(validMillis/1000);
                        response.addCookie(cookie);
                    }

                }else{
                    map.put("state","fail");
                }
            }catch (MalformedJwtException | SignatureException e){
                     map.put("state","signature");//改造簽名,或者無效的Token
                     map.put("loginAuth","該Token無效");//改造簽名,或者無效的Token
            }catch (ExpiredJwtException e){
                     map.put("state","expired");//改造簽名,或者無效的Token
                     map.put("loginAuth","Token已經過時");
            }catch (Exception e) {
            e.printStackTrace();
            map.put("state","fail");
            }
            return map;
    }

    @RequestMapping(params = "index",method = RequestMethod.GET)
    @ResponseBody
    public Object index (HttpServletRequest request, HttpServletResponse response){
        Map<string, object=""> map = new HashMap<>();
        //从COOKIE中查找,模拟访问,可以集成容器管理
        Cookie[] cookies = request.getCookies();
        if (cookies!=null) {
            for (int i = cookies.length-1; i >= 0; i--) {
                Cookie cookie = cookies[i];
                if (cookie.getName().equals(MD5Util.MD5Encode("MD5SING", "UTF-8").toUpperCase())) {
                    //跳过登陆
                    map.put("index","采用Redis登录");
                    return map;
                }
            }
        }
        map.put("index","你的Token已经销毁");
        return map;
    }

}
        <dependency>
            <groupid>io.jsonwebtoken</groupid>
           <artifactid>jjwt</artifactid>
            <version>0.7.0</version>
        </dependency>

目录:
1.Java开源生鲜电商平台-系统简介 https://www.cnblogs.com/jurendage/p/9012355.html
2.Java开源生鲜电商平台-系统架构与技术选型(源码可下载) https://www.cnblogs.com/jurendage/p/9012922.html
3.Java开源生鲜电商平台-盈利模式详解(源码可下载) https://www.cnblogs.com/jurendage/p/9016411.html
4.Java开源生鲜电商平台-用户表的设计(源码可下载) https://www.cnblogs.com/jurendage/p/9017912.html
5.Java开源生鲜电商平台-商品表的设计(源码可下载) https://www.cnblogs.com/jurendage/p/9022917.html
6.Java开源生鲜电商平台-订单表的设计(源码可下载) https://www.cnblogs.com/jurendage/p/9029467.html
7.Java开源生鲜电商平台-支付模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9034444.html
8.Java开源生鲜电商平台-购物车模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9039195.html
9.Java开源生鲜电商平台-推荐系统模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9044283.html
10.Java开源生鲜电商平台-财务系统模块的设计与架构(源码可下载)https://www.cnblogs.com/jurendage/p/9049318.html
11.Java开源生鲜电商平台-账单模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9053417.html
12.Java开源生鲜电商平台-提现模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9053523.html
13.Java开源生鲜电商平台-订单抽成模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9059304.html
14.Java开源生鲜电商平台-搜索模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9062649.html
15.Java开源生鲜电商平台-售后模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9066307.html
16.Java开源生鲜电商平台-监控模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9070442.html
17.Java开源生鲜电商平台-异常模块的设计与架构(源码可下载)https://www.cnblogs.com/jurendage/p/9075219.html
18.Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9081062.html
19.Java开源生鲜电商平台-安全设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9087581.html
20.Java开源生鲜电商平台-优惠券设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9091587.html
21.Java开源生鲜电商平台-通知模块设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9095078.html
22.Java开源生鲜电商平台-团购模块设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9098368.html
23.Java开源生鲜电商平台-服务器部署设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9103339.html
24.Java开源生鲜电商平台-系统报表设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9108863.html
25.Java开源生鲜电商平台-源码地址公布与思考和建议 https://www.cnblogs.com/jurendage/p/9114796.html
26.Java开源生鲜电商平台-RBAC系统权限的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9120168.html
27.Java开源生鲜电商平台-物流配送的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9124947.html
28.Java开源生鲜电商平台-库存管理设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9130455.html
29.Java开源生鲜电商平台-销售管理设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9131557.html
30.Java开源生鲜电商平台-电商促销业务分析设计与系统架构(源码可下载) https://www.cnblogs.com/jurendage/p/9137815.html
31.Java开源生鲜电商平台-一次代码重构的实战案例(源码可下载) https://www.cnblogs.com/jurendage/p/9143105.html
32.Java开源生鲜电商平台-商品价格的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9148906.html
33.Java开源生鲜电商平台-定时器,定时任务quartz的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9153835.html
34.Java开源生鲜电商平台-高并发的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9159020.html
35.Java开源生鲜电商平台-技术方案与文档下载(源码可下载) https://www.cnblogs.com/jurendage/p/9162190.html
36.Java开源生鲜电商平台-积分,优惠券,会员折扣,签到、预售、拼团、砍价、秒杀及抽奖等促销模块架构设计(源码可下载) https://www.cnblogs.com/jurendage/p/9165594.html
37.Java开源生鲜电商平台-供应链模块的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9171467.html
38.Java开源生鲜电商平台-会员积分系统的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9176010.html
39.Java开源生鲜电商平台-redis缓存在商品中的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9181380.html
40.Java开源生鲜电商平台-商品无限极目录的设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9185990.html
41.Java开源生鲜电商平台-物流动态费率、免运费和固定运费设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9189736.html
42.Java开源生鲜电商平台-商品的spu和sku数据结构设计与架构(源码可下载) https://www.cnblogs.com/jurendage/p/9194551.html
43.Java开源生鲜电商平台-你应该保留的一些学习态度与学习方法(源码可下载) https://www.cnblogs.com/jurendage/p/9197096.html

Java开源生鲜电商平台-Java后端生成Token架构与设计详解(源码可下载),如果需要下载的话,可以在我的github下面进行下载。

https://github.com/137071249/

群号:168096884

原文地址:https://www.cnblogs.com/jurendage/p/9219041.html

时间: 2024-10-09 20:29:31

Java开源生鲜电商平台-Java后端生成Token架构与设计详解(源码可下载)的相关文章

Java开源生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案(源码可下载)

Java开源生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案(源码可下载) 说明:Java开源生鲜电商中OMS订单系统中并发问题和锁机制的探讨与解决方案: 问题由来     假设在一个订单系统中(以火车票订单系统为例),用户A,用户B都要预定从成都到北京的火车票,A.B在不同的售票窗口均同时查询到了某车厢卧铺中.下铺位有空位.用户A正在犹豫订中铺还是下铺,这时用户B果断订购了下铺.当用户A决定订下铺时,系统提示下铺已经被预订,请重新选择铺位.在这个系统场景中,我们来探讨一下,火车票

Java开源生鲜电商平台-系统架构与技术选型(源码可下载)

Java开源生鲜电商平台-系统架构与技术选型(源码可下载) 1.  硬件环境 公司服务器 2.   软件环境 2.1  操作系统 Linux CentOS 6.8系列 2.2 反向代理/web服务器 Nginx 2.3 应用服务器 Jdk7+ Tomcat 7 2.4 数据库 Mysql 5.6.x 2.5 消息队列(可选) Rabbitmq/rocketmq 2.6 缓存(可选) Redis 3.x 3.工程构建和管理工具 1.Maven 开发人员已经很熟悉了.此处略 2.Jenkins Je

Java开源生鲜电商平台-用户表的设计(源码可下载)

Java开源生鲜电商平台-用户表的设计(源码可下载) 说明:由于该系统属于B2B平台,不设计到B2C的架构. 角色分析:买家与卖家. 由于买家与卖家所填写的资料都不一样,需要建立两站表进行维护,比如:buyer,seller. 这样进行数据库的解耦,任何一方的变动都互不影响,但是我想集中式管理,以及一些业务个性化要求,我就增加了一个users表.表结构如下: 账号唯一键,所以做了唯一键索引, 账号的准确性采用手机短信验证. 根据类型区分买家与卖家,登陆的时候,采用的就是users这种表进行维护

Java开源生鲜电商平台-监控模块的设计与架构(源码可下载)

Java开源生鲜电商平台-监控模块的设计与架构(源码可下载) 说明:Java开源生鲜电商平台-监控模块的设计与架构,我们谈到监控,一般设计到两个方面的内容: 1. 服务器本身的监控.(比如:linux服务器的CPU,内存,磁盘IO等监控) 2. 业务系统的监控.  (比如:业务系统性能的监控,SQL语句的监控,请求超时的监控,用户输入的监控,整个请求过程时间的监控,优化等等) 1. 服务器本身的监控 说明:由于Java开源生鲜电商平台采用的是阿里云的linux CentOS服务器,由于阿里云本身

Java开源生鲜电商平台-通知模块设计与架构(源码可下载)

Java开源生鲜电商平台-通知模块设计与架构(源码可下载) 说明:对于一个生鲜的B2B平台而言,通知对于我们实际的运营而言来讲分为三种方式:           1. 消息推送:(采用极光推送)           2. 主页弹窗通知.(比如:现在有什么新的活动,有什么新的优惠等等)           3. 短信通知.(对于短信通知,这个大家很熟悉,我们就说下我们如何从代码层面对短信进行分层的分析与架构) 1. 消息推送 说明:目前市场上的推送很多,什么极光推送,环信,网易云等等,都可以实现秒

Java开源生鲜电商平台-RBAC系统权限的设计与架构(源码可下载)

Java开源生鲜电商平台-RBAC系统权限的设计与架构(源码可下载) 说明:根据上面的需求描述以及对需求的分析,我们得知通常的一个中小型系统对于权限系统所需实现的功能以及非功能性的需求,在下面我们将根据需求从技术角度上分析实现的策略以及基于目前两种比较流行的权限设计思想来讨论关于权限系统的实现. 1.1.       技术策略 l         身份认证 在B/S的系统中,为识别用户身份,通常使用的技术策略为将用户的身份记录在Session中,也就是当用户登录时即获取用户的身份信息,并将其记录

Java开源生鲜电商平台-销售管理设计与架构(源码可下载)

Java开源生鲜电商平台-销售管理设计与架构(源码可下载) 说明:在Java开源生鲜电商平台中,销售人员我们称为跟餐饮店老板沟通与下载APP的一类地推人员.(所谓地推指的就是一个一个上门拜访.) 由于销售人员有以下几类特性: 1. 时间随意性,他们并不类似技术或者性质人员,需要天天呆在办公室,他们是需要去外面,时间上具有随意性. 2. 行动随意性 ,他们的行动过于随意,每天也不用来打卡,每天就是按照计划去拜访客户,然后推销生鲜电商APP,让客户来进行下单,那么行为很随意,站在公司的角度 我们是没

Java开源生鲜电商平台-技术方案与文档下载(源码可下载)

说明:任何一个好的项目,都应该有好的文档与设计方案,包括需求文档,概要设计,详细设计,测试用例,验收报告等等,类似下面这个图: 有以下几个管理域: 1. 开发域. 2. 管理域 3. 基线域 4. 产品域 1.  开发域包括以下几个维度: 例如:需求开发中,应该包括以下几个文档: 2,系统设计中又包括: 3. 基线域 其中需求基线又包括: 化状态:A--增加,M--修改,D--删除 目录 1       项目简介..........................................

Java开源生鲜电商平台-物流动态费率、免运费和固定运费设计与架构(源码可下载)

Java开源生鲜电商平台-物流动态费率.免运费和固定运费设计与架构(源码可下载) 说明:物流配送环节常见的有包邮,免运费,或者偏远地区动态费率,还存在一些特殊的情况,固定费率,那么如何进行物流的架构与设计呢? 运费之困惑 在淘宝买过东西的亲们,应该都有过这样的体会--每次购物,都要在运费上和商家讨价还价,商议好运费后,还得下达订单等待卖家修改了才能付款,每次都如此,实在很不方便.而且当碰到运费很贵时(跨省的),那往往就会导致这次买卖告吹.无论在淘宝,还是在其它网站,当购买大件商品时,如果按照实际