美文网首页
react-native keycloak使用总结

react-native keycloak使用总结

作者: 朱传武 | 来源:发表于2021-07-08 23:53 被阅读0次

    keycloak是一个开源的单点登录库,包括一整套前后端整体的开源库,最近一个德国客户自己搭建了keycloak服务器,需要在客户端做登录。其实我之前没用过keycloak,对这个东西很陌生,趁机研究了一把,文档还没有完全吃透,但是已经帮他解决了问题,这里先记录一下使用过程,后期如有类似项目或更深入项目可直接使用。由于我之前对keycloak一无所知,当用户把clientid、realm、以及authurl发我的时候我一脸懵逼,这个东西怎么用?于是我打算自己照着官网教程自己搭一下后台试试,这样测试就方便了……
    keycloak官网
    下载最新版本(目前是14):

    image.png
    官方快速开始教程:https://www.keycloak.org/getting-started/getting-started-zip
    这里记录一下流程:
    1、下载解压之后,进入bin 目录下,(macos)执行:
    ./standalone.sh
    

    2、等待服务器起来之后打开url:http://localhost:8080/auth,创建管理员账号,

    image.png
    3、登录管理员账号http://localhost:8080/auth/admin/master/console/
    4、创建新得realm

    这里我创建的是myrealm,记住名字很关键!!!
    5、创建系统用户并设置密码:
    image.png
    image.png
    我这里设置的是1317272927@qq.com/123456789
    6、http://localhost:8080/auth/realms/myrealm/account/#/ 登录新创建的用户,进行测试。
    这里服务器设置就完成了,好了我们进行app端的开发。
    react-native keycloak

    一开始我查了好多keycloak相关的库,基本都是通过打开系统浏览器的方式进行单点登录,我花了大约有7-8个小时进行了调研测试,最终这个库在如果需要打开浏览器的方式进行登录的话,能正常work:
    https://github.com/react-keycloak/react-native-keycloak
    它的用法如下:

    const keycloak = new RNKeycloak({
      url: "http://localhost:8080/auth",
      realm: "myrealm",
      clientId: "myclient"
    });
    
    <ReactNativeKeycloakProvider
          authClient={keycloak}
          onInitError={(event, error) => {
            console.log("onKeycloakEvent", event, error);
          }}
        
          initOptions={{
            redirectUri: "myapp://Homepage",
            onLoad: "login-required",
            // if you need to customize "react-native-inappbrowser-reborn" View you can use the following attribute
            inAppBrowserOptions: {
              // For iOS check: https://github.com/proyecto26/react-native-inappbrowser#ios-options
              // For Android check: https://github.com/proyecto26/react-native-inappbrowser#android-options
            },
          }}
        >
          <Login />
        </ReactNativeKeycloakProvider>
    
    export default function StartScreen() {
      const { keycloak } = useKeycloak();
      const goLogin = useCallback(() => {
        keycloak?.login();
      }, []);
      return (
        <View style={tailwind("h-full pt-16 px-8 ")}>
          <View style={tailwind("justify-center items-center h-1/4")}>
            <Image
              style={tailwind("w-14 h-14 ")}
              resizeMode="contain"
              source={require("../../assets/logo.png")}
            />
          </View>
          <Placeholder
            Animation={Fade}
            style={tailwind("h-1/2")}
            //   Left={PlaceholderMedia}
            //   Right={PlaceholderMedia}
          >
            <PlaceholderLine height={35} />
            <View style={tailwind("justify-center items-center")}>
              <Image
                style={tailwind("w-1/3 mb-16 mt-8")}
                source={require("../../assets/image-placeholder.jpg")}
              />
            </View>
            <PlaceholderLine height={25} />
            <PlaceholderLine height={25} />
          </Placeholder>
          <View>
            <View
              style={tailwind("flex-row items-center justify-center -mt-8 mb-12")}
            >
              <Text style={tailwind("text-blue-400 text-2xl")}>←</Text>
              <Text style={tailwind("text-blue-400 text-2xl ml-8")}>→</Text>
            </View>
            <Button mode="contained" uppercase={false} onPress={goLogin}>
              Get started
            </Button>
          </View>
        </View>
      );
    }
    

    效果如下:


    Jul-08-2021 23-43-36.gif

    打开的登录网页是keycloak默认的界面,看教程可以定制,但是我没仔细看,这里先不写了,后面需要的时候再回来补充,这里刚开始一直提示“invalid redict_url"需要服务端修改如下:


    image.png
    这里需要注意,一旦用户登录成功,只要你没有logout,app就是一直登录的装填,因为他登录的时候是用系统浏览器进行的登录,应该session存在了系统浏览器里面(只是猜想没有验证,因为我删除之后,再安装,app还是登录状态)
    app用restful登录:

    但是用户的需求是不打开浏览器进行,需要进行restful登录:
    https://www.keycloak.org/docs/latest/server_development/,最终在这里找到了restful相关的接口,app端登录变为如下:

    const goLogin = useCallback(async () => {
        const details: any = {
          username: userName,
          password: passWord,
          grant_type: "password",
          client_id: "candis",
        };
        let formBody = [];
        for (var property in details) {
          var encodedKey = encodeURIComponent(property);
          var encodedValue = encodeURIComponent(details[property]);
          formBody.push(encodedKey + "=" + encodedValue);
        }
        const result = await fetch(
          "https://keycloak.dev-my.candis.io/auth/realms/candis/protocol/openid-connect/token",
          {
            body: formBody.join("&"),
            headers: {
              "content-type": "application/x-www-form-urlencoded",
            },
            method: "POST",
            mode: "cors",
          }
        );
        const resultJson = await result.json();
        console.log(resultJson);
        if (resultJson.access_token) {
          NavigationService.navigate("AuthentificationScreen");
        } else {
          setVisible(true);
        }
      }, []);
    

    注意需要:"content-type": "application/x-www-form-urlencoded",
    服务器返回值:

    {
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJWTUlIUG1tOTJPQ241aWtGTFBZdVd3djR2SVVZTzB3SFlqMXRsRkliZ25FIn0.eyJleHAiOjE2MjY4NDA3NjgsImlhdCI6MTYyNTYzMTE2OCwianRpIjoiNzllZThmOTYtMzBlNy00YjdkLTkyZDQtY2VhYTNjNDg4ODc1IiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay5kZXYtbXkuY2FuZGlzLmlvL2F1dGgvcmVhbG1zL2NhbmRpcyIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI0ZjhlMGZhOS0xODc4LTRmNzctYmZkNy03OTc5MDU4ZDk0Y2MiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJjYW5kaXMiLCJzZXNzaW9uX3N0YXRlIjoiZDRhNDRkMTYtNWZkZS00NjNmLWE3MWUtMjMwNTEzODQyODdiIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJjYW5kaXMuaW8iLCIqIiwiaHR0cDovL2xvY2FsaG9zdDozMDAwIiwiaHR0cHM6Ly9jYW5kaXMuaW8iXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9mZmxpbmVfYWNjZXNzIGVtYWlsIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6IkppYW5sb25nIE5pZSIsInByZWZlcnJlZF91c2VybmFtZSI6Im5pZWppYW5sb25nMTFAZ21haWwuY29tIiwibG9jYWxlIjoiZW4iLCJnaXZlbl9uYW1lIjoiSmlhbmxvbmciLCJmYW1pbHlfbmFtZSI6Ik5pZSIsImVtYWlsIjoibmllamlhbmxvbmcxMUBnbWFpbC5jb20ifQ.GJc-b4eaPcHKWSfqzv1BXunY-D0LHF40SmFAYQJBp_sGgf_Cpx6_iIPDGc51psFK5hz7mwOU-VINi2RnOl37ylyHkZs1e9gkg_OQVkTOgHr8bY8-f1mByBfuBdAStjK904_Vr4L8_We7BCyPlkylYCJzaLsTafd58NAK-wcBPPhahQEr5-yXFczJxg43IU2RzH4xVMk2xu7Fnzf4fv5_EJ5LZIr4rHmVP3BFCXq0drd9hbIt0R7OMbyN-WbZbZEAzDijqnivcgsvL3mOyoePfT8iu3--zUnE2FLOPu_fU3jO85dPomIpz2TbQzMXqNsQQoLF6AEzDur9mUo4rizJ6Q",
    "expires_in": 1209600,
    "refresh_expires_in": 0,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjOTQ0YjI0NS1lOGFiLTRjN2EtYTg2MS1hZDY0MjAyZjA2NTMifQ.eyJpYXQiOjE2MjU2MzExNjgsImp0aSI6IjdkMGFiNTg4LTE3MDctNGZiYS04ZmVlLWQ3MTlkMDMyMmMwYiIsImlzcyI6Imh0dHBzOi8va2V5Y2xvYWsuZGV2LW15LmNhbmRpcy5pby9hdXRoL3JlYWxtcy9jYW5kaXMiLCJhdWQiOiJodHRwczovL2tleWNsb2FrLmRldi1teS5jYW5kaXMuaW8vYXV0aC9yZWFsbXMvY2FuZGlzIiwic3ViIjoiNGY4ZTBmYTktMTg3OC00Zjc3LWJmZDctNzk3OTA1OGQ5NGNjIiwidHlwIjoiT2ZmbGluZSIsImF6cCI6ImNhbmRpcyIsInNlc3Npb25fc3RhdGUiOiJkNGE0NGQxNi01ZmRlLTQ2M2YtYTcxZS0yMzA1MTM4NDI4N2IiLCJzY29wZSI6Im9mZmxpbmVfYWNjZXNzIGVtYWlsIHByb2ZpbGUifQ.xM3AaV2Synhfspo4-fU9djuHP5Po725hLE-vMFaESoE",
    "token_type": "bearer",
    "not-before-policy": 0,
    "session_state": "d4a44d16-5fde-463f-a71e-23051384287b",
    "scope": "offline_access email profile"
    }
    

    keycloak 可以再服务端很容易的和现有系统集成,从而无需担心用户认证问题。

    相关文章

      网友评论

          本文标题:react-native keycloak使用总结

          本文链接:https://www.haomeiwen.com/subject/jdjxpltx.html