可视化软件grafana如何用oauth实现第三方授权登录

​前言


    无论是什么行业的企业或业务,有时候我们需要查看历史数据---了解业务,总结规律,发现异常。

    grafana作为数据可视化软件之一,支持多种数据源,可灵活配置图表,得到你想要的数据呈现效果,也有很多开放的api,方便和其他系统集成,也就是说grafana直接读取你的数据,至于如何展示,在它上面设置就可以了,而且开源、免费。如果数据量多,需要高性能,可以把数据存在influxDb等时序数据库。

    但是遗憾的是,系统本身没有中文版本,如果需要汉化:可参考我之前的这篇文章:https://blog.csdn.net/koppel/article/details/90272136。


    近期需要做grafana的权限控制,虽然官网有介绍多种方式,但是不够详细,网上的帖子也比较旧,想做好还是要花一些时间的。一年前写的上面这篇简短的文章也有四千多阅读量, 有人关注grafana也说明了物联网和大数据的发展迅速,因此这次把oauth的也记录下来,给大家参考。

 

 

需求


我自己有业务的管理后台,不同的管理员有不同的项目权限,同时自己服务器部署了grafana。之前是使用了匿名登录(auth.anonymous enable=true),所有人都能看到所有项目,现在希望在自己的管理后台点击按钮跳转到grafana后台,也有对应的权限。

想实现的效果就是:

1、能不能那边登录了,这边自动登录

2、用户仅能查看自己项目的图表数据。

3、除了登录,权限管理能不能也同步

 

使用自带的权限管理功能


如果不开发,使用自带的权限也是可以的。

    grafana有几个概念:user用户、org组织、team团队、role角色。我的项目中只有一个组织,据说创建多个组织需要重新配置数据源。系统默认三个角色。grafana从6.4以上支持role mapping,如果没猜错的话,会支持更多的角色,但是由于我用的是6.2,默认只有admin、viewer和editor三个角色。

    上面两种都不太合适做权限管理。但是可以通过team充当角色。人可以属于team,team又和dashboard关联。

这样做的好处:

    不需要开发。

坏处:

    需要手动维护权限。如果你有自己的系统,那又要在grafana维护权限,权限改动两边都要更新,可能遗忘导致两边权限不一致。

 

使用oauth登录


为什么没选择ldap?

    除了oauth,grafana还支持ldap(轻型目录访问协议),但是应该需要搭建服务,而oauth是更主流的方案。

目录:

步骤1:修改grafana配置文件

步骤2:开发三个接口

步骤3:调试和验证

 


步骤1:修改grafana配置文件

我的文件在/etc/grafana/grafana.ini

[server]

root_url = http://xxx.com:3000

这里的root_url需要修改为真实的地址,因为授权回调的redirect_uri是这个。

 

配置oauth

[auth.generic_oauth]

enabled = true

name = OAuth

allow_sign_up = true

client_id = some_id

client_secret = some_secret

scopes = user:email,read:org

auth_url = http://xxx.com/login/oauth/authorize

token_url = http://xxx.com/login/oauth/token

api_url = http://xxx.com/login/oauth/userinfo

 

这里主要是需要后端提供三个接口:

auth_url是授权接口。token_url是获取token。api_url是获取用户信息接口,下文会继续介绍。

 

配置好之后可以重启grafana:

./bin/grafana-server -config="/etc/grafana/grafana.ini"

 

步骤2:开发三个接口

这里主要介绍请求流程,入参和返回值的形式,假设uid是123456。

我是把uid作为code,同时作为token,在实际的项目中,后端最好使用JWT做token的验证。(关于JWT可自行百度)。

 

接口1:get请求

请求地址:

https://xxx.com/login/oauth/authorize?access_type=online&client_id=some_id&redirect_uri=http%3A%2F%2Fxxx.com%3A3000%2Flogin%2Fgeneric_oauth&response_type=code&scope=user%3Aemail+read%3Aorg&state=JAh0jkpkBbBW4mkVHpWnylC9eJk1pvwAQgWar6bAXxQ%3D

 

接口返回做重定向:

http://xxx.com:3000/login/generic_oauth?state={state}&code=123456

 

接口2:post请求

请求地址:

http://xxx.com/login/oauth/token

post参数:

{"code":"123456","grant_type":"authorization_code","redirect_uri":"http://xxx.com:3000/login/generic_oauth"}

返回值:

{

    "access_token": "123456",

    "token_type": "Bearer",

    "expiry_in": "",

     "refresh_token": ""

}

 

接口3:

 

get请求

header:

authorization:Bearer 123456

返回值:

{

"name":"test",

"email":"test@test"

}

 

代码参考(php laravel):

<?phpnamespace App\Http\Controllers\BigData;use App\Http\Controllers\Controller;use Illuminate\Http\Request;use \LeanCloud\Query as LeanQuery;use Auth;class OAuthController extends Controller {    public function auth(Request $request) {        if (Auth::user() == NULL) {            return response()->json(["msg" => "not login"]);        }        $redirect_uri = $request->input("redirect_uri");        $state = $request->input("state");        $url = $redirect_uri . "?state=" . $state . "&code=" . Auth::user()->objectId;        return response()->redirectTo($url);    }    // code 换取 token    public function token(Request $request) {        $myObj = new \stdClass();        $myObj->access_token = $request->input("code");        $myObj->token_type = "Bearer";// jwt要是这个        $myObj->expiry_in = "";        $myObj->refresh_token = "";        $myJSON = json_encode($myObj);        return response($myJSON);    }    public function userinfo(Request $request) {        $header_auth = \Request::header("authorization");        $uid = substr($header_auth, 7);        if (!$uid) {            return response()->json(["msg" => ""]);        }        // 根据uid获取用户        $query = new LeanQuery("_User");        $data = $query->get($uid);        $nickName = $data->get("nickName");        $email = $data->get("username") . "@test";// 需要是电子邮箱格式        return response()->json(["email" => $email, "name" => $nickName]);    }}

 

步骤3:调试和验证

首先访问http://xxx.com:3000/login要能看到登录页面的oauth入口,证明配置生效了

 

    点击按钮后,会请求:http://xxx.com:3000/login/generic_oauth。我们需要开发提供的三个oauth接口,都是在login/generic_oauth里面静默调用的。

    先请求第一个auth_url接口获取code。然后拿code请求第二个token_url接口,获取token。然后把token放到header中请求第三个api_url接口。然后根据第三个接口返回的email和name自动注册登录。

    调试过程中如果接口有问题,grafana会把接口的返回值比如报错,都打印到日志中,查看日志中的信息即可。

 


 

    oauth自动登录开发好之后,可以调用grafana的api开发权限管理:让指定的team拥有dashboard的查看权限,让用户属于某些team。api参考文档:https://grafana.com/docs/grafana/latest/http_api/dashboard_permissions/

    至此,你的grafana就可以和现有项目无缝衔接,使用更加方便。

 

    本文的部分内容来自mediam,查看原文:

https://medium.com/@manivannan_data/grafana-generic-oauth-login-authentication-c31a1ce56a45

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值