Skip to content

Commit

Permalink
Merge pull request #28 from Laceyoo/main
Browse files Browse the repository at this point in the history
device模式下通过后端转发请求获取user_code
  • Loading branch information
freedomkk-qfeng authored Jan 2, 2024
2 parents f3ec507 + c843eed commit b63e917
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 19 deletions.
23 changes: 23 additions & 0 deletions controller/oauth2_device_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,29 @@ type ReqDeviceData struct {
ExpiresIn int `json:"expires_in"`
}

type ReqUserCodeData struct {
InitialAddress string `json:"initialAddress"`
}

func getUserCode(c *gin.Context) {
reqData := ReqUserCodeData{}
if err := c.Bind(&reqData); err != nil {
c.JSON(http.StatusOK, handleError(err.Error()))
return
}
method := "POST"
apiAddr := reqData.InitialAddress
body := fmt.Sprintf("")
header := make(map[string]string)

res, err := models.HandleRequest(method, apiAddr, g.UserAgent, body, g.Config().Timeout, header)
if err != nil {
c.JSON(http.StatusOK, handleError(err.Error()))
return
}
c.JSON(http.StatusOK, handleSuccess(res))
}

func deviceFlow(c *gin.Context) {
reqData := ReqDeviceData{}
if err := c.Bind(&reqData); err != nil {
Expand Down
1 change: 1 addition & 0 deletions controller/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func Routes(r *gin.Engine) {
playground.Use(NoCache())
playground.POST("/oauth2/pkce", pkce)
playground.POST("/oauth2/device_flow", deviceFlow)
playground.POST("/oauth2/user_code", getUserCode)
playground.POST("/oauth2/client_credentials", clientCredentials)
playground.POST("/oauth2/password", passwordMode)
playground.POST("/oauth2/authorization_code", exchangeTokenByCode)
Expand Down
6 changes: 6 additions & 0 deletions front-standalone/src/api/playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ export const fetchACTokenByPassword = (data) => {
};

/** Device Flow */
/** Step 1 */
/** Get user_code */
export const fetchUserCode = (data) => {
return http.post<Result>("/oauth2/user_code", data);
}

/** Step 2 */
/** Get access_token with device_code */
export const fetchACTokenByDevice = (data) => {
Expand Down
51 changes: 32 additions & 19 deletions front-standalone/src/views/playground/components/Device.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { onMounted, reactive, ref, watch } from 'vue'
import {ElMessage, FormInstance} from 'element-plus'
import { LocalStorageService } from "/@/utils/persistence"
import useClipboard from 'vue-clipboard3';
import { fetchACTokenByDevice, fetchApiData, fetchRefreshToken} from "/@/api/playground";
import {fetchACTokenByDevice, fetchApiData, fetchRefreshToken, fetchUserCode} from "/@/api/playground";
import * as QRCode from 'qrcode'
import axios from "axios";
Expand Down Expand Up @@ -83,7 +83,7 @@ function updateReqAndRes() {
// Step 1
const activeName = ref('1');
const s1Data = reactive({
authorization_endpoint: "",
token_endpoint: "",
// redirect_uri: window.location.href.split("?")[0],
scope: "",
response_type: "device_code",
Expand All @@ -94,7 +94,7 @@ const initialAddress = ref("");
// 修改的同时拼接成url显示在Grant Url中
function handleS1Change() {
initialAddress.value = s1Data.authorization_endpoint.concat(
initialAddress.value = s1Data.token_endpoint.concat(
"?response_type=device_code",
s1Data.scope?.length > 0 ? "&scope=".concat(s1Data.scope) : "",
props.cfgData.client_id?.length > 0 ? "&client_id=".concat(props.cfgData.client_id) : ""
Expand All @@ -118,19 +118,32 @@ function handleDeviceFlow() {
lss.addItem(cs);
}
// window.location.href = initialAddress.value;
axios.post(initialAddress.value).then((res) => {
user_code.value = res.data.user_code
verification_uri.value = res.data.verification_uri
device_code.value = res.data.device_code
expires_in.value = res.data.expires_in
// 检查是否获取到user_code,若长度不为0,则跳到Step 2
if (device_code.value.length === 0 || user_code.value.length === 0 || verification_uri.value.length === 0) {
ElMessage.error("Authorization failed. Check your configurations.");
return;
const dataObject = {
initialAddress: initialAddress.value
};
fetchUserCode(dataObject).then(({code, msg, data}) => {
if (code === 0) {
const {request, response, rawjson, example} = data;
if (rawjson.user_code === undefined || rawjson.user_code === '')
return
// const {interval, verification_uri, user_code, expires_in, device_code} = rawjson || {};
if (user_code !== undefined && user_code !== null) {
user_code.value = rawjson.user_code
verification_uri.value = rawjson.verification_uri
device_code.value = rawjson.device_code
expires_in.value = rawjson.expires_in
// 检查是否获取到user_code,若长度不为0,则跳到Step 2
if (device_code.value.length === 0 || user_code.value.length === 0 || verification_uri.value.length === 0) {
ElMessage.error("Authorization failed. Check your configurations.");
return;
}
activeName.value = '2';
// 轮询是否获取到token
tokenAvailablelong(expires_in.value);
}
} else {
ElMessage.error("Get user_code failed. Please check your configuration!")
}
activeName.value = '2';
// 轮询是否获取到token
tokenAvailablelong(expires_in.value);
}).catch((err) => {
console.error('get user code failed: ', err)
})
Expand Down Expand Up @@ -371,9 +384,9 @@ async function generateQRCode(url) {
}
watch(props.cfgData, (newValue) => {
s1Data.authorization_endpoint = newValue.authorization_endpoint;
s1Data.token_endpoint = newValue.token_endpoint;
s1Data.scope = newValue.default_scope;
initialAddress.value = newValue.authorization_endpoint.concat(
initialAddress.value = newValue.token_endpoint.concat(
"?response_type=device_code",
newValue.default_scope?.length > 0 ? "&scope=".concat(newValue.default_scope) : "",
newValue.client_id?.length > 0 ? "&client_id=".concat(newValue.client_id) : "",
Expand Down Expand Up @@ -417,8 +430,8 @@ const handleDrag = (floatButton, container) => {
<span class="stepTitle">Step 1: Request for Device Flow Authorization</span>
</template>
<el-scrollbar class="fitSide" ref="agS1ContainerRef">
<h4 style="text-align: left;margin: 0">Authorization Endpoint</h4>
<el-input v-model="s1Data.authorization_endpoint" disabled/>
<h4 style="text-align: left;margin: 0">accessToken Endpoint</h4>
<el-input v-model="s1Data.token_endpoint" disabled/>
<!-- <h4 style="text-align: left;margin: 0">Redirect Uri</h4>-->
<!-- <el-input v-model="s1Data.redirect_uri" disabled/>-->
<h4 style="text-align: left;margin: 0">Scope</h4>
Expand Down

0 comments on commit b63e917

Please sign in to comment.