API開放平台接口設計-------令牌方式


1.需求:現在A公司與B公司進行合作,B公司需要調用A公司開放的外網接口獲取數據,如何保證外網開放接口的安全性?

2,使用令牌方式

  比如支付寶對外提供支付的接口,愛樂生公司需要調用支付寶的接口。在愛樂生調用支付寶接口的時候,支付寶進行過濾器攔截,查看參數中的accessToken信息,是否能在redis緩存中的找到對應的公司,且同時對對方開放。如果沒問題,則可以調用接口。

  令牌的設計方式一般會設計到以下幾個參數:

App_Name       表示機構名稱

App_ID          應用id

App_Secret      應用密鑰  (可更改)

Is_flag           是否可用 (是否對某個機構開放)

access_token  上一次access_token

 

 

3,生成accessToken 的接口:

package com.zfb.api.controller;

import java.util.UUID;

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.zfb.base.Response;
import com.zfb.entity.AppEntity;
import com.zfb.mapper.AppMapper;
import com.zfb.response.IndexResponse;
import com.zfb.utils.BaseRedisService;

@Controller
public class Index extends Response {

    @Autowired
    private BaseRedisService baseRedisService;
    @Autowired
    private AppMapper appMapper;

    private static final long TIMEOUT = 60 * 60 * 60;

    @RequestMapping("/index")
    @ResponseBody
    private String index() {
        return "index";
    }

    @RequestMapping("/postAccessToken")
    @ResponseBody
    private String postAccessToken() {
        AppEntity appEntity  = new AppEntity();
        appEntity.setAppId("1QA2was");//不可變
        appEntity.setAppName("aiyusheng");
        appEntity.setAppSecret("ssss");
        appEntity.setId(1);
        appEntity.setIsFlag(0);
        getAccessToken(appEntity);
        return "index";
    }
    /**
     * 訪問獲取accessToken appid+appsecret 1,如果找這個機構,說明無權訪問 2,如果if_flag為1,說明接口關閉了
     * 3,如果找到這個機構,且為0的話,開始生成access_token 3.1,redis 緩存中先刪除之前的access_oken
     * 3.2,創建新的access_token,同時放入到緩存中
     * 
     * @return
     */
    
    @RequestMapping("/getAccessToken")
    @ResponseBody
    private String getAccessToken(AppEntity appEntity) {
        AppEntity findApp = appMapper.findApp(appEntity);
        // 如果找到這個機構,且為0的話,開始生成access_token
        IndexResponse response = firstCheck(new IndexResponse(), findApp);
        if (response.getRtnCode() != 200) {
            return "fail";
        }
        String accessToken = findApp.getAccessToken();
        baseRedisService.delKey(accessToken);
        String generateAccessToken = generateAccessToken(findApp.getAppId(), findApp.getAppSecret());
        //更新mysql 數據庫
        appMapper.updateAccessToken(generateAccessToken, appEntity.getAppId());
        return "success";
    }

    public String generateAccessToken(String appid, String appSecret) {
        String accessToken = UUID.randomUUID().toString() + "_" + appid + "_" + appSecret;
        baseRedisService.setString(accessToken, appid, TIMEOUT);
        return accessToken;
    }

    public IndexResponse firstCheck(IndexResponse indexResponse, AppEntity findApp) {
        if (findApp == null) {
            indexResponse.setResultError("沒有對應的機構");
            return null;
        }
        if (findApp.getIsFlag() != 0) {
            indexResponse.setResultError("沒有對" + findApp.getAppName() + "開放");
            return indexResponse;
        }
        // 查詢成功
        indexResponse.setRtnCode(200);
        return indexResponse;
    }

}

過濾器:

package com.zfb.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.zfb.utils.BaseRedisService;

@WebFilter(filterName = "tokenAccessFilter", urlPatterns = "/pay/*")
public class TokenAccessFilter implements Filter {

    @Autowired
    private BaseRedisService baseRedisService;

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        String accessToken = request.getParameter("accessToken");
        if (!StringUtils.isEmpty(accessToken)) {
            //redis 里面的key 是 accessToken  value是appid
            String appid = (String) baseRedisService.getString(accessToken);
            // 代表沒有過期
            if (!StringUtils.isEmpty(appid)) {
                chain.doFilter(request, response);
            }
        }

    }

    public void destroy() {

    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM