grafana接入oauth2

grafana接入oauth2

说明

IP组件
192.168.146.18grafana
192.168.146.19nginx(项目运行服务器)
192.168.208.97本地oauth接入测试服务

grafana配置

安装grafana之后,配置文件grafana.ini默认会在/etc/grafana路径下

修改grafana.ini配置

vim grafana.ini 

要修改部分

[server]
# Protocol (http, https, h2, socket)
;protocol = http

# The ip address to bind to, empty will bind to all interfaces
;http_addr =

# The http port  to use
;http_port = 3000

# The public facing domain name used to access grafana from a browser
;domain = localhost

# Redirect to correct domain if host header does not match domain
# Prevents DNS rebinding attacks
;enforce_domain = false

# The full public facing url you use in browser, used for redirects and emails
# If you use reverse proxy and sub path specify full url (with sub path)
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
root_url = http://192.168.146.18:3000 #grafana访问地址 用于授权回调

[auth.generic_oauth]
enabled = true # 默认是false,改为true。打开oauth认证
name = OAuth
allow_sign_up = true
client_id = some_id #自研平台唯一client_id
client_secret = some_secret #自研平台唯一client_secret
scopes = user:email,read:org
auth_url = http://192.168.208.97:8080/login/oauth/authorize #自研平台授权认证接口
token_url = http://192.168.208.97:8080/login/oauth/token #自研平台生成token接口
api_url = http://192.168.208.97:8080/login/oauth/userinfo #自研平台验证token并返回用户信息

接口开发

注意:这些接口都是grafana静默调用

授权认证接口

请求方式:get

请求路径:/login/oauth/authorize

请求参数

类型名称描述
Stringaccess_typeonline
StringstateJTlwwAomCy2-H0maDX7JJpzVOCA_-RUfjqlftMoMt7w=当前请求唯一密文
Stringredirect_urihttp://192.168.146.18:3000/login/generic_oauth配置文件root_url加固定/login/generic_oauth,用于重定向
Stringresponse_typecode
Stringscopeid email nickname配置文件scope
Stringclient_idsome_id平台唯一client_id

接口内部实现client_id验证和用户信息查询验证之后将用户id和参数state用做重定向参数

重定向地址:http://192.168.146.18:3000/login/generic_oauth?state={state}&code=xxx

代码示例

@RestController
@Slf4j
@RequestMapping("/login/oauth")
public class AuthApi {

    @GetMapping("/authorize")
    public void authorize(@RequestParam Map<String, String> params, HttpServletResponse response, HttpServletRequest request) throws IOException {
        for (Map.Entry<String, String> entry : params.entrySet()) {
            System.out.println(entry.getKey() + "-------------" + entry.getValue());
        }

        /* 核心业务逻辑 验证client_id 和用户信息 获取用户id*/
        String userId = "xxx";
        builder.append("state=").append(params.get("state")).append("&code=").append(JWTUtil.createToken(userId, "jwt".getBytes(StandardCharsets.UTF_8)));
        
        String url = "http://192.168.146.18:3000/login/generic_oauth?" + builder.toString();
        System.out.println(url);
        response.sendRedirect(url);
    }
}

生成token接口

请求方式:post

请求路径:/login/oauth/token

请求参数

类型名称描述
Stringcodexxx授权接口的用户id
Stringgrant_typeauthorization_code固定值
Stringredirect_urihttp://192.168.146.18:3000/login/generic_oauth配置文件root_url加固定/login/generic_oauth,用于重定向

返回参数

类型名称描述
Stringaccess_token认证token
Stringtoken_typeBearer验证token会将其添加到token首部
Stringexpiry_in
Stringrefresh_token

代码示例

 @PostMapping("/token")
    public TokenResponse token(TokenParam tokenParam){
        System.out.println(tokenParam);
		
        /* 核心业务逻辑 生成token */
        String token = xxx;
        TokenResponse response = new TokenResponse();
        response.setAccess_token(xxx);
        response.setToken_type("Bearer");
        response.setExpiry_in("1");
        response.setRefresh_token("123456");

        return response;
    }

验证token接口

请求方式:get

请求路径:/login/oauth/userinfo

请求头信息

类型名称描述
StringauthorizationBearer xxxtoken_type + access_token

请求参数:无

返回参数

类型名称描述
Stringnamelzz用户名
Stringemailliuzhuzheng@talkweb.com.cn用户邮箱

代码示例

@GetMapping("/userinfo")
    public User userInfo(HttpServletRequest request){
        System.out.println(2222);

        String authorization = request.getHeader("authorization");
        System.out.println(authorization);

        /* 核心业务逻辑,验证token并设置用户信息*/
        
        User user = new User();
        user.setEmail("liuzhuzheng@talkweb.com.cn");
        user.setName("lzz");

        return user;
    }

测试

访问http://192.168.146.18:3000/login/generic_oauth便可实现用户注册登录grafana

其他代码

TokenParam类

@Data
public class TokenParam {
    private String code;

    private String grant_type;

    private String redirect_uri;
}

TokenResponse类

@Data
public class TokenResponse {
    private String access_token;
    
    private String token_type;
    
    private String expiry_in;
    
    private String refresh_token;
}

User类

@Data
public class User {
    private String id;

    private String email;

    private String name;
}

nginx配置代理

如果是将grafana嵌入自己的项目工程中,因为默认grafana设置samesite=lax导致跨域情况下setCookie不能传递,此时需要通过grafana进行代理来实现同域传递

grafana配置文件修改

[server]
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
root_url = http://192.168.146.19/grafana #修改路径
serve_from_sub_path = true #默认为false

nginx配置文件添加

添加grafana相关请求转发

server {
    listen       80;
    server_name  localhost;	
    location  /grafana{
            proxy_pass http://192.168.146.18:3000;
            proxy_redirect             off;
            proxy_set_header           Host $host;
            proxy_set_header           X-Real-IP $remote_addr;
            proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header           X-Forwarded-Proto $scheme;
            client_max_body_size       100m;
            client_body_buffer_size    256k;
            proxy_connect_timeout      500;
            proxy_send_timeout         2000;
            proxy_read_timeout         2000;
            proxy_ignore_client_abort  on;
            proxy_buffer_size          128k;
            proxy_buffers              4 256k;
            proxy_busy_buffers_size    256k;
            proxy_temp_file_write_size 256k;
        }

        location  /login/oauth{
            proxy_set_header Host  $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://192.168.208.89:8080;
        }
        location  /public{
            proxy_pass   http://192.168.146.18:3000/public;
        }
        location  /avatar{
            proxy_pass   http://192.168.146.18:3000/avatar;
        }
    }

oauth接口修改

授权认证接口中最后需要转发回login/generic_oauth,此时要添加上grafana前缀 如下

@RestController
@Slf4j
@RequestMapping("/login/oauth")
public class AuthApi {
    @GetMapping("/authorize")
    public void authorize(@RequestParam Map<String, String> params, HttpServletResponse response, HttpServletRequest request) throws IOException {
        for (Map.Entry<String, String> entry : params.entrySet()) {
            System.out.println(entry.getKey() + "-------------" + entry.getValue());
        }

        /* 核心业务逻辑 验证client_id 和用户信息 获取用户id*/
        String userId = "xxx";
        builder.append("state=").append(params.get("state")).append("&code=").append(JWTUtil.createToken(userId, "jwt".getBytes(StandardCharsets.UTF_8)));

        /* 需要修改的地方 /login/generic_oauth/ ------> grafana/login/generic_oauth*/
        String url = "http://192.168.146.18:3000/grafana/login/generic_oauth?" + builder.toString();
        System.out.println(url);
        response.sendRedirect(url);
    }
}

至此 访问http://192.168.146.19/grafana或者是对应面板的详细地址都能跳转登录页并成功登录。

踩坑点

1、如果是本地测试在windows下安装nginx,可能会导致关不掉,此时可以通过任务管理器关闭

2、如果测试次数过多,可能会导致有多个grafana_session,清除一下当前页面的cookie就行了

3、切记配置grafana配置文件中serve_from_sub_path = true

4、安装的nginx要在当前前端页面部署的服务器上,且监听的是同一个端口,因为端口不同也是跨域

<think>好的,我需要帮助用户了解如何创建或选择一个用于接收用户输入的API接口。首先,用户提到的引用里提到了API是接口的一种实现方式,特别是提到了webservice接口,这可能是一个方向。用户的需求是实现用户输入信息的接入,所以需要明确用户输入的具体场景和需求。 首先,我需要考虑用户可能的应用场景,比如是网页表单、移动应用还是其他平台。不同的场景可能需要不同类型的API接口。例如,如果是Web应用,可能需要RESTful API;如果是企业内部系统,可能需要SOAP(webservice)接口。 接下来,用户需要创建或选择API接口。这里有几个步骤:确定需求、选择协议类型、设计接口规范、实现和测试、安全措施、文档编写以及部署维护。需要一步步引导用户完成这些步骤。 在确定需求时,要明确数据类型、频率和传输方式。例如,用户可能需要接收文本、文件或者结构化数据。如果是高频次的数据,可能需要考虑性能优化和负载均衡。 选择协议类型时,REST和SOAP是常见选项。REST轻量级,适合Web和移动应用,而SOAP适合需要高安全性和事务支持的企业环境。还有GraphQL,适合需要灵活查询的场景。 设计接口规范包括定义端点、HTTP方法、数据格式(JSON或XML)和状态码。这部分需要详细说明,比如POST方法用于提交数据,使用JSON格式更常见。 实现和测试方面,用户可能需要使用框架如Flask或Django来快速搭建API,并用Postman进行测试。这里可以给出简单的代码示例,比如用Python Flask创建一个接收POST请求的端点。 安全性是重要的一环,需要提到HTTPS、身份验证(如JWT、OAuth)、数据加密和输入验证,防止注入攻击。 文档和维护部分,强调API文档的重要性,可以使用Swagger生成,并持续监控和维护接口性能。 然后,根据用户提供的引用,特别是引用[2]提到的webservice接口,可能需要补充关于SOAP的内容,比如WSDL文件和如何生成服务端代码。 最后,生成相关问题,帮助用户深入理解,比如如何选择协议、安全措施有哪些、测试工具推荐等。 需要确保回答结构清晰,步骤明确,符合用户要求的系统级指令,比如使用正确的中文和LaTeX格式,行内公式用$...$,独立公式用$$...$$。不过当前问题中没有涉及数学公式,所以可能不需要使用LaTeX,但需要检查是否有遗漏。同时,引用要正确标注,如引用[^1]和[^2]的来源,但用户提供的引用内容有限,可能需要假设这些引用与API类型和实现相关。 总结回答的结构应该是分步骤说明如何创建或选择API接口,每个步骤详细解释,并结合用户提到的引用内容,确保引用自然融入回答中,并在末尾添加相关问题。</think>### 如何创建或选择用于接收用户输入的API接口? #### 1. **明确需求场景** - **数据类型**:确定接收的输入是文本、文件、JSON/XML结构化数据,还是其他格式(例如表单数据)。 - **传输频率**:预估每秒请求量(QPS),高频场景需考虑性能优化[^1]。 - **使用环境**:是Web应用(需RESTful API)、移动端(需轻量级接口),还是企业级系统(需SOAP协议)? #### 2. **选择协议类型** - **RESTful API**(推荐场景:Web/移动端) 特点:基于HTTP,使用标准方法(GET/POST/PUT/DELETE),数据格式通常为JSON。 示例:用户提交表单数据到`POST /api/submit`端点。 - **SOAP/WebService**(推荐场景:企业级系统) 特点:基于XML,严格规范,支持事务和安全扩展。 示例:通过WSDL文件定义接口,生成服务端代码。 - **GraphQL**(推荐场景:灵活查询需求) 特点:客户端可自定义返回字段,减少冗余数据传输。 #### 3. **设计接口规范** - **端点设计**:如`POST /api/user-input`用于接收输入。 - **参数定义**: ```json { "user_id": "string", "content": "string", "timestamp": "ISO 8601" } ``` - **状态码**:明确返回码(如200-成功、400-参数错误、500-服务端错误)。 #### 4. **实现与测试** - **框架选择**: - Python:Flask、Django REST Framework ```python from flask import Flask, request app = Flask(__name__) @app.route('/api/submit', methods=['POST']) def handle_input(): data = request.get_json() # 处理数据逻辑 return {'status': 'success'}, 200 ``` - Java:Spring Boot(支持SOAP和REST) - **测试工具**:Postman(模拟请求)、Swagger(自动化文档与测试)。 #### 5. **安全措施** - **HTTPS**:强制使用加密传输。 - **身份验证**: - API Key:简单场景。 - OAuth 2.0/JWT:高安全需求场景(如用户登录)。 - **输入验证**:过滤SQL注入、XSS攻击(如正则表达式检查)。 #### 6. **文档与维护** - **文档生成**:使用Swagger UI或Postman生成交互式文档。 - **监控报警**:通过Prometheus/Grafana监控接口性能,设置错误报警。 --- ### 示例场景 假设需接收用户反馈表单: 1. 选择RESTful API,设计`POST /api/feedback`。 2. 使用Flask实现,JSON格式验证用户输入的邮箱和内容。 3. 部署时启用HTTPS,并通过JWT验证用户身份。 ---
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值