站点更新:2018-03-27 15:37:33
This commit is contained in:
commit
97257044a4
6
.idea/emacs.xml
Normal file
6
.idea/emacs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="EmacsSettings">
|
||||||
|
<option name="emacsPath" value="/usr/bin/emacs" />
|
||||||
|
</component>
|
||||||
|
</project>
|
9
.idea/jwt.iml
Normal file
9
.idea/jwt.iml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/jwt.iml" filepath="$PROJECT_DIR$/.idea/jwt.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
53
.idea/watcherTasks.xml
Normal file
53
.idea/watcherTasks.xml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectTasksOptions">
|
||||||
|
<TaskOptions isEnabled="true">
|
||||||
|
<option name="arguments" value="fmt $FilePath$" />
|
||||||
|
<option name="checkSyntaxErrors" value="true" />
|
||||||
|
<option name="description" />
|
||||||
|
<option name="exitCodeBehavior" value="ERROR" />
|
||||||
|
<option name="fileExtension" value="go" />
|
||||||
|
<option name="immediateSync" value="false" />
|
||||||
|
<option name="name" value="go fmt" />
|
||||||
|
<option name="output" value="$FilePath$" />
|
||||||
|
<option name="outputFilters">
|
||||||
|
<array />
|
||||||
|
</option>
|
||||||
|
<option name="outputFromStdout" value="false" />
|
||||||
|
<option name="program" value="$GoExecPath$" />
|
||||||
|
<option name="runOnExternalChanges" value="false" />
|
||||||
|
<option name="scopeName" value="Project Files" />
|
||||||
|
<option name="trackOnlyRoot" value="true" />
|
||||||
|
<option name="workingDir" value="" />
|
||||||
|
<envs>
|
||||||
|
<env name="GOROOT" value="$GOROOT$" />
|
||||||
|
<env name="GOPATH" value="$GOPATH$" />
|
||||||
|
<env name="PATH" value="$GoBinDirs$" />
|
||||||
|
</envs>
|
||||||
|
</TaskOptions>
|
||||||
|
<TaskOptions isEnabled="true">
|
||||||
|
<option name="arguments" value="-w $FilePath$" />
|
||||||
|
<option name="checkSyntaxErrors" value="true" />
|
||||||
|
<option name="description" />
|
||||||
|
<option name="exitCodeBehavior" value="ERROR" />
|
||||||
|
<option name="fileExtension" value="go" />
|
||||||
|
<option name="immediateSync" value="false" />
|
||||||
|
<option name="name" value="goimports" />
|
||||||
|
<option name="output" value="$FilePath$" />
|
||||||
|
<option name="outputFilters">
|
||||||
|
<array />
|
||||||
|
</option>
|
||||||
|
<option name="outputFromStdout" value="false" />
|
||||||
|
<option name="program" value="goimports" />
|
||||||
|
<option name="runOnExternalChanges" value="false" />
|
||||||
|
<option name="scopeName" value="Project Files" />
|
||||||
|
<option name="trackOnlyRoot" value="true" />
|
||||||
|
<option name="workingDir" value="" />
|
||||||
|
<envs>
|
||||||
|
<env name="GOROOT" value="$GOROOT$" />
|
||||||
|
<env name="GOPATH" value="$GOPATH$" />
|
||||||
|
<env name="PATH" value="$GoBinDirs$" />
|
||||||
|
</envs>
|
||||||
|
</TaskOptions>
|
||||||
|
</component>
|
||||||
|
</project>
|
302
.idea/workspace.xml
Normal file
302
.idea/workspace.xml
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="847c5949-378a-4c01-9318-d1db88c22ef9" name="Default" comment="" />
|
||||||
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
|
<option name="TRACKING_ENABLED" value="true" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="FileEditorManager">
|
||||||
|
<leaf>
|
||||||
|
<file leaf-file-name="showtoken.go" pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/token/showtoken.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="527">
|
||||||
|
<caret line="39" column="24" lean-forward="true" selection-start-line="39" selection-start-column="24" selection-end-line="39" selection-end-column="24" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file leaf-file-name="token.go" pinned="false" current-in-tab="true">
|
||||||
|
<entry file="file://$PROJECT_DIR$/token/token.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="251">
|
||||||
|
<caret line="38" column="5" lean-forward="false" selection-start-line="38" selection-start-column="5" selection-end-line="38" selection-end-column="5" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
</leaf>
|
||||||
|
</component>
|
||||||
|
<component name="GOROOT" path="/usr/local/opt/go/libexec" />
|
||||||
|
<component name="IdeDocumentHistory">
|
||||||
|
<option name="CHANGED_PATHS">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/cmd/verify.go" />
|
||||||
|
<option value="$PROJECT_DIR$/cmd/show.go" />
|
||||||
|
<option value="$PROJECT_DIR$/token/signtoken.go" />
|
||||||
|
<option value="$PROJECT_DIR$/cmd/sign.go" />
|
||||||
|
<option value="$PROJECT_DIR$/token/token.go" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
|
||||||
|
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
|
||||||
|
<component name="JsGulpfileManager">
|
||||||
|
<detection-done>true</detection-done>
|
||||||
|
<sorting>DEFINITION_ORDER</sorting>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectFrameBounds" extendedState="6">
|
||||||
|
<option name="x" value="1920" />
|
||||||
|
<option name="y" value="23" />
|
||||||
|
<option name="width" value="1440" />
|
||||||
|
<option name="height" value="877" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectView">
|
||||||
|
<navigator currentView="ProjectPane" proportions="" version="1">
|
||||||
|
<flattenPackages />
|
||||||
|
<showMembers />
|
||||||
|
<showModules />
|
||||||
|
<showLibraryContents />
|
||||||
|
<hideEmptyPackages />
|
||||||
|
<abbreviatePackageNames />
|
||||||
|
<autoscrollToSource />
|
||||||
|
<autoscrollFromSource />
|
||||||
|
<sortByType />
|
||||||
|
<manualOrder />
|
||||||
|
<foldersAlwaysOnTop value="true" />
|
||||||
|
</navigator>
|
||||||
|
<panes>
|
||||||
|
<pane id="Scratches" />
|
||||||
|
<pane id="ProjectPane">
|
||||||
|
<subPane>
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="jwt" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="jwt" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="jwt" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="jwt" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="cmd" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="jwt" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="jwt" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="token" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
<pane id="Scope" />
|
||||||
|
</panes>
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
<property name="go.sdk.automatically.set" value="true" />
|
||||||
|
<property name="settings.editor.selected.configurable" value="watcher.settings" />
|
||||||
|
</component>
|
||||||
|
<component name="RunDashboard">
|
||||||
|
<option name="ruleStates">
|
||||||
|
<list>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="StatusDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration name="go build main.go" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true">
|
||||||
|
<module name="jwt" />
|
||||||
|
<working_directory value="$PROJECT_DIR$/" />
|
||||||
|
<go_parameters value="-i" />
|
||||||
|
<parameters value="show -t -" />
|
||||||
|
<kind value="FILE" />
|
||||||
|
<filePath value="$PROJECT_DIR$/main.go" />
|
||||||
|
<package value="github.com/ehlxr/jwt" />
|
||||||
|
<directory value="$PROJECT_DIR$/" />
|
||||||
|
</configuration>
|
||||||
|
<recent_temporary>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="Go Build.go build main.go" />
|
||||||
|
</list>
|
||||||
|
</recent_temporary>
|
||||||
|
</component>
|
||||||
|
<component name="ShelveChangesManager" show_recycled="false">
|
||||||
|
<option name="remove_strategy" value="false" />
|
||||||
|
</component>
|
||||||
|
<component name="ToolWindowManager">
|
||||||
|
<frame x="1920" y="23" width="1440" height="877" extended-state="6" />
|
||||||
|
<editor active="true" />
|
||||||
|
<layout>
|
||||||
|
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||||
|
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32992327" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.17381974" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
|
||||||
|
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.24964234" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||||
|
<window_info id="Docker" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32992327" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||||
|
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.39897698" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||||
|
</layout>
|
||||||
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="1" />
|
||||||
|
</component>
|
||||||
|
<component name="VcsContentAnnotationSettings">
|
||||||
|
<option name="myLimit" value="2678400000" />
|
||||||
|
</component>
|
||||||
|
<component name="XDebuggerManager">
|
||||||
|
<breakpoint-manager>
|
||||||
|
<breakpoints>
|
||||||
|
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
|
||||||
|
<url>file://$PROJECT_DIR$/token/token.go</url>
|
||||||
|
<line>45</line>
|
||||||
|
<properties />
|
||||||
|
<option name="timeStamp" value="4" />
|
||||||
|
</line-breakpoint>
|
||||||
|
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
|
||||||
|
<url>file://$PROJECT_DIR$/token/token.go</url>
|
||||||
|
<line>39</line>
|
||||||
|
<properties />
|
||||||
|
<option name="timeStamp" value="7" />
|
||||||
|
</line-breakpoint>
|
||||||
|
</breakpoints>
|
||||||
|
<option name="time" value="8" />
|
||||||
|
</breakpoint-manager>
|
||||||
|
<watches-manager />
|
||||||
|
</component>
|
||||||
|
<component name="editorHistoryManager">
|
||||||
|
<entry file="file://$PROJECT_DIR$/main.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="247">
|
||||||
|
<caret line="13" column="20" lean-forward="false" selection-start-line="13" selection-start-column="20" selection-end-line="13" selection-end-column="20" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/cmd/root.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="317">
|
||||||
|
<caret line="47" column="18" lean-forward="true" selection-start-line="46" selection-start-column="8" selection-end-line="47" selection-end-column="18" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/cmd/show.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="129">
|
||||||
|
<caret line="39" column="22" lean-forward="true" selection-start-line="39" selection-start-column="22" selection-end-line="39" selection-end-column="22" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/util/tokenutil.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="185">
|
||||||
|
<caret line="34" column="5" lean-forward="false" selection-start-line="34" selection-start-column="5" selection-end-line="34" selection-end-column="5" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/../../spf13/pflag/string.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="171">
|
||||||
|
<caret line="9" column="0" lean-forward="true" selection-start-line="9" selection-start-column="0" selection-end-line="9" selection-end-column="0" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/../../spf13/pflag/uint64.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="95">
|
||||||
|
<caret line="5" column="5" lean-forward="false" selection-start-line="5" selection-start-column="5" selection-end-line="5" selection-end-column="5" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/../../spf13/pflag/duration.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="95">
|
||||||
|
<caret line="7" column="5" lean-forward="false" selection-start-line="7" selection-start-column="5" selection-end-line="7" selection-end-column="5" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/../../spf13/pflag/flag.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="142">
|
||||||
|
<caret line="174" column="8" lean-forward="false" selection-start-line="174" selection-start-column="8" selection-end-line="174" selection-end-column="8" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/../../spf13/pflag/flag_test.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="379">
|
||||||
|
<caret line="1072" column="14" lean-forward="true" selection-start-line="1072" selection-start-column="14" selection-end-line="1072" selection-end-column="14" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/token/signtoken.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="583">
|
||||||
|
<caret line="119" column="0" lean-forward="false" selection-start-line="119" selection-start-column="0" selection-end-line="119" selection-end-column="0" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/cmd/verify.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="613">
|
||||||
|
<caret line="53" column="27" lean-forward="false" selection-start-line="53" selection-start-column="22" selection-end-line="53" selection-end-column="27" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/cmd/sign.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="602">
|
||||||
|
<caret line="51" column="48" lean-forward="false" selection-start-line="51" selection-start-column="48" selection-end-line="51" selection-end-column="48" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/token/showtoken.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="527">
|
||||||
|
<caret line="39" column="24" lean-forward="true" selection-start-line="39" selection-start-column="24" selection-end-line="39" selection-end-column="24" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/token/token.go">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="251">
|
||||||
|
<caret line="38" column="5" lean-forward="false" selection-start-line="38" selection-start-column="5" selection-end-line="38" selection-end-column="5" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
</project>
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
84
cmd/root.go
Normal file
84
cmd/root.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
homedir "github.com/mitchellh/go-homedir"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cfgFile string
|
||||||
|
|
||||||
|
// rootCmd represents the base command when called without any subcommands
|
||||||
|
var rootCmd = &cobra.Command{
|
||||||
|
Use: "jwt",
|
||||||
|
Short: "JWT(Json Web Token) 工具",
|
||||||
|
Long: `JWT(Json Web Token) 工具
|
||||||
|
用于生成、验证、查看 JWT`,
|
||||||
|
Version: "v0.0.1",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||||
|
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||||
|
func Execute() {
|
||||||
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cobra.OnInitialize(initConfig)
|
||||||
|
|
||||||
|
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.jwt.yaml)")
|
||||||
|
// rootCmd.Flags().BoolP("help", "h", false, "path to JWT token to verify or '-' to read from stdin")
|
||||||
|
rootCmd.Flags().BoolP("version", "v", false, "show version of the jwt.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// initConfig reads in config file and ENV variables if set.
|
||||||
|
func initConfig() {
|
||||||
|
if cfgFile != "" {
|
||||||
|
// Use config file from the flag.
|
||||||
|
viper.SetConfigFile(cfgFile)
|
||||||
|
} else {
|
||||||
|
// Find home directory.
|
||||||
|
home, err := homedir.Dir()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search config in home directory with name ".jwt" (without extension).
|
||||||
|
viper.AddConfigPath(home)
|
||||||
|
viper.SetConfigName(".jwt")
|
||||||
|
}
|
||||||
|
|
||||||
|
viper.AutomaticEnv() // read in environment variables that match
|
||||||
|
|
||||||
|
// If a config file is found, read it in.
|
||||||
|
if err := viper.ReadInConfig(); err == nil {
|
||||||
|
fmt.Println("Using config file:", viper.ConfigFileUsed())
|
||||||
|
}
|
||||||
|
}
|
49
cmd/show.go
Normal file
49
cmd/show.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/ehlxr/jwt/token"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// showCmd represents the show command
|
||||||
|
var showCmd = &cobra.Command{
|
||||||
|
Use: "show",
|
||||||
|
Short: "查看 JWT Token",
|
||||||
|
Long: `
|
||||||
|
查看 JWT Token`,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if err := token.ShowToken(cmd); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(showCmd)
|
||||||
|
|
||||||
|
showCmd.Flags().StringP("token", "t", "", "path or arg of JWT token to verify, '-' to read from clipboard")
|
||||||
|
}
|
52
cmd/sign.go
Normal file
52
cmd/sign.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/ehlxr/jwt/token"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// signCmd represents the sign command
|
||||||
|
var signCmd = &cobra.Command{
|
||||||
|
Use: "sign",
|
||||||
|
Short: "JWT 签名",
|
||||||
|
Long: `
|
||||||
|
JWT 签名`,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if err := token.SignToken(cmd); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(signCmd)
|
||||||
|
|
||||||
|
signCmd.Flags().StringP("data", "d", "", "path or json to claims object to sign, '-' to read from clipboard, or '+' to use only -claim args")
|
||||||
|
signCmd.Flags().StringP("key", "k", "", "path of keyfile or key argument")
|
||||||
|
signCmd.Flags().VarP(make(token.ArgList), "claims", "c", "add additional claims. may be used more than once")
|
||||||
|
signCmd.Flags().VarP(make(token.ArgList), "header", "H", "add additional header params. may be used more than once")
|
||||||
|
}
|
52
cmd/verify.go
Normal file
52
cmd/verify.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/ehlxr/jwt/token"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// verifyCmd represents the verify command
|
||||||
|
var verifyCmd = &cobra.Command{
|
||||||
|
Use: "verify",
|
||||||
|
Short: "JWT token 验证",
|
||||||
|
Long: `
|
||||||
|
JWT token 验证`,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if err := token.VerifyToken(cmd); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(verifyCmd)
|
||||||
|
|
||||||
|
verifyCmd.Flags().StringP("token", "t", "", "path or arg of JWT token to verify, '-' to read from clipboard")
|
||||||
|
verifyCmd.Flags().StringP("key", "k", "", "path of keyfile or key argument")
|
||||||
|
}
|
6
demo.json
Normal file
6
demo.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"foo": "bar",
|
||||||
|
"exp": "2108-02-03",
|
||||||
|
"info": "jjjkk",
|
||||||
|
"other": "靠捡垃圾困了就睡打发士大夫斯柯达房间爱劳动法"
|
||||||
|
}
|
1
demo.token
Normal file
1
demo.token
Normal file
@ -0,0 +1 @@
|
|||||||
|
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIyMTA4LTAyLTAzIiwiZm9vIjoiYmFyIiwiaW5mbyI6ImpqamtrIiwib3RoZXIiOiLpnaDmjaHlnoPlnL7lm7DkuoblsLHnnaHmiZPlj5Hlo6vlpKflpKvmlq_mn6_ovr7miL_pl7TniLHlirPliqjms5UifQ.lwIz_fjoxHkgaBLUnBsRO0_zCmx4bEKNP_noW0dIGSSV5dPReb_E41Dg38G0ZB6tUFgH9k7aKsUUdMO3-ixRQ-nVT7qryLVti72G7Bpxy-_0FcwPWsvOl1ic8wCMtXLcL2FmcxFt4VC7nky1iAMCYn0iWyBxuPboNxBYNJF2TYB5rsfoLGgQ-okFVahZWDrdiepIlwFh-SkzrgLYzFhUgfCvCOFyTn65aNzJxY_3vxd4OSl6ks8C6J1qF7FZbFVFpcaHebZHjqg2rS3q0CdhN1IpGhEHC4dktpbeAzUYTPaohJWa-Rftthg4iM9DOFz8NBB_rNxyCYBfsbcywk8X2g
|
27
key/private-key.pem
Normal file
27
key/private-key.pem
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpQIBAAKCAQEAtLcqUewX4sOPUUcocUi4EMMi25I52j9AHpphV4xZ5uUBzUuE
|
||||||
|
sEuomPhvpElrVGAnla6856nrsSOTnw/pQ+wHkZLXXBbJOqdOH8wohch6v3lJoJDS
|
||||||
|
FsCc+Y2OfolxZ8qz1Qq+AyvFGv4NIM0rWsfosrSsMDnQzLFtUoAfCMGU4uas2H1u
|
||||||
|
Wfh+dDaABgxshAtmBuTyFJ/q36mGAznGzN7jVUSxv+pgI6AyEgxiIKOmFrz9qm6N
|
||||||
|
s/H9fONQznnZouFZc0p3PME4xJcpdjET2tpACBZr6p7znFCm7t2BMrC37wznHUxC
|
||||||
|
xP3XOugH9fs90EXV3XwPHZTAkvxvs8fpeDfGhwIDAQABAoIBAQCbsyhqNuEJhnZn
|
||||||
|
j8h/eijkgEv7JAxmRpKnC1oNBSa8MdkQmR00i6sySPJfeMZZhxLz+v5VFuiz0TQy
|
||||||
|
GpJe6/BFc1/LvvIXb+h2qv7K7UUczZIrHjt0UPWuaVE5IpAr3dB9IGk/8Ck9rV+A
|
||||||
|
QGU3LQAHYHTuhBGrGr9XEn4qnCb8KlH/h12YEomIlp0+5TG6j4U6gzCJYM8MSmmP
|
||||||
|
ms3JYP3jCvCD+UWcHXcWd/MAs4vfQAcCSvrrwrjHB0SZNAgUeIYxiXje1sKS5SU5
|
||||||
|
tCKp7B7+PwBXkOMPPBxB93GsEmc6Tnw48hvl/xhOThOQ3zI608mzd83YQ7XU0cxO
|
||||||
|
0LtAdyURAoGBAOFD3Ba1mL4MdYuSMpEH4Teu+rmuVBvF9tIA8uI73ZZDxOrklZRr
|
||||||
|
XUtDcDwlsaSgk2ATz15+Rr+pYT3H3xl95P/xj2LG5SNY2OmiANALYHm71wDAa3xD
|
||||||
|
th5p6QJ1wqQxzEBewwqXrm49YZr5eNU+rvTjsW4YcSB9ObYBbSUGvqf5AoGBAM1f
|
||||||
|
Qu4pYrIfkPFhgDQaepDhZ41NGIaDmukZcorVPnliy4+anMoivvVjVNkUb7FyHm8h
|
||||||
|
Fo2q6gSyeGDVGg/6QbMrzIrN5fqjCK4M4cBwd3sboctjI8fwJQB2+Wb6iOCQMU1W
|
||||||
|
DbJ/edhOdLZ71lQMd+f5iQvhiZJPGLZnAxHyhoJ/AoGBANqvrU9illkR8V9A29RO
|
||||||
|
SQds2L1ADykzQ01WXHTi11iUi+vZY5lFrbluS9woX8/Jj6k7MhqzDm3suplmmyC9
|
||||||
|
Rn5ufNvQ6QwqqdIOUymlkdA8WhrBstddSMU33lxkBESwj3CCTmjPHiipcEMqI3Mp
|
||||||
|
umHFVi/ijJiU2Vzm/5VtedPJAoGAQ5WI0hVefF209ipu5TadhRYYXMC1RHcEwJb2
|
||||||
|
QcfhMlMXyB9KX57Flr1ki7eU9iEm8M1DvcU0E+2jfcJDPGTPwCW2vyr49t02Gwj0
|
||||||
|
Nb8NIr86JFNwz/gwRRHiC0iBSN1KzDd4dHhM4akX8YGZS7l6sCVHO1iyTCqpaEVI
|
||||||
|
FlzodQMCgYEAlMyxMLwaePE1NPgPqUeLcjfId42AZ64sVjoNG3awzj6pr3kV9mjp
|
||||||
|
3GxFFDLdELZcsD5aJ5YSFbjMvUqSyyuFlZOAut06iUtPAN7fC57PdXGpcf2YkoK3
|
||||||
|
PPK4mrwSlB4Onk8BQ3HfyGC5jzNsl+mnUHrRljWyzhdwQXtj65zQCD4=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
9
key/public-key.pem
Normal file
9
key/public-key.pem
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtLcqUewX4sOPUUcocUi4
|
||||||
|
EMMi25I52j9AHpphV4xZ5uUBzUuEsEuomPhvpElrVGAnla6856nrsSOTnw/pQ+wH
|
||||||
|
kZLXXBbJOqdOH8wohch6v3lJoJDSFsCc+Y2OfolxZ8qz1Qq+AyvFGv4NIM0rWsfo
|
||||||
|
srSsMDnQzLFtUoAfCMGU4uas2H1uWfh+dDaABgxshAtmBuTyFJ/q36mGAznGzN7j
|
||||||
|
VUSxv+pgI6AyEgxiIKOmFrz9qm6Ns/H9fONQznnZouFZc0p3PME4xJcpdjET2tpA
|
||||||
|
CBZr6p7znFCm7t2BMrC37wznHUxCxP3XOugH9fs90EXV3XwPHZTAkvxvs8fpeDfG
|
||||||
|
hwIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
27
main.go
Normal file
27
main.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/ehlxr/jwt/cmd"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cmd.Execute()
|
||||||
|
}
|
68
token/showtoken.go
Normal file
68
token/showtoken.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package token
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
jwt "github.com/dgrijalva/jwt-go"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// showToken pretty-prints the token on the command line.
|
||||||
|
func ShowToken(cmd *cobra.Command) error {
|
||||||
|
flagToken := cmd.LocalFlags().Lookup("token").Value.String()
|
||||||
|
flagDebug := promptDebug()
|
||||||
|
flagCompact := promptCompact()
|
||||||
|
|
||||||
|
// get the token
|
||||||
|
tokData, err := loadData(flagToken)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Couldn't read token: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim possible whitespace from token
|
||||||
|
tokData = regexp.MustCompile(`\s*$`).ReplaceAll(tokData, []byte{})
|
||||||
|
if flagDebug {
|
||||||
|
fmt.Fprintf(os.Stderr, "Token len: %v bytes\n", len(tokData))
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := jwt.Parse(string(tokData), nil)
|
||||||
|
if token == nil {
|
||||||
|
return fmt.Errorf("malformed token: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the token details
|
||||||
|
fmt.Println("Header:")
|
||||||
|
if err := printJSON(token.Header, flagCompact); err != nil {
|
||||||
|
return fmt.Errorf("Failed to output header: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Claims:")
|
||||||
|
if err := printJSON(token.Claims, flagCompact); err != nil {
|
||||||
|
return fmt.Errorf("Failed to output claims: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
122
token/signtoken.go
Normal file
122
token/signtoken.go
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
// Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package token
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/atotto/clipboard"
|
||||||
|
|
||||||
|
jwt "github.com/dgrijalva/jwt-go"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create, sign, and output a token. This is a great, simple example of
|
||||||
|
// how to use this library to create and sign a token.
|
||||||
|
func SignToken(cmd *cobra.Command) error {
|
||||||
|
flagData := cmd.LocalFlags().Lookup("data").Value.String()
|
||||||
|
flagClaims := cmd.LocalFlags().Lookup("claims").Value.(ArgList)
|
||||||
|
flagHead := cmd.LocalFlags().Lookup("header").Value.(ArgList)
|
||||||
|
flagKey := cmd.LocalFlags().Lookup("key").Value.String()
|
||||||
|
flagDebug := promptDebug()
|
||||||
|
|
||||||
|
flagAlg, err := promptAlg()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Prompt flagAlg failed %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the token data from command line arguments
|
||||||
|
tokData, err := loadData(flagData)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Couldn't read data: %v", err)
|
||||||
|
} else if flagDebug {
|
||||||
|
fmt.Fprintf(os.Stderr, "Token len: %v bytes\n", len(tokData))
|
||||||
|
fmt.Fprintf(os.Stderr, "Token data: %v \n", string(tokData))
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse the JSON of the claims
|
||||||
|
var claims jwt.MapClaims
|
||||||
|
if err := json.Unmarshal(tokData, &claims); err != nil {
|
||||||
|
return fmt.Errorf("Couldn't parse claims JSON: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add command line claims
|
||||||
|
if len(flagClaims) > 0 {
|
||||||
|
for k, v := range flagClaims {
|
||||||
|
claims[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the key
|
||||||
|
var key interface{}
|
||||||
|
key, err = loadData(flagKey)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Couldn't read key: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the signing alg
|
||||||
|
alg := jwt.GetSigningMethod(flagAlg)
|
||||||
|
if alg == nil {
|
||||||
|
return fmt.Errorf("Couldn't find signing method alg: %v", flagAlg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new token
|
||||||
|
token := jwt.NewWithClaims(alg, claims)
|
||||||
|
|
||||||
|
// add command line headers
|
||||||
|
if len(flagHead) > 0 {
|
||||||
|
for k, v := range flagHead {
|
||||||
|
token.Header[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isEs(flagAlg) {
|
||||||
|
if k, ok := key.([]byte); !ok {
|
||||||
|
return fmt.Errorf("Couldn't convert key data to key")
|
||||||
|
} else {
|
||||||
|
key, err = jwt.ParseECPrivateKeyFromPEM(k)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if isRs(flagAlg) {
|
||||||
|
if k, ok := key.([]byte); !ok {
|
||||||
|
return fmt.Errorf("Couldn't convert key data to key")
|
||||||
|
} else {
|
||||||
|
key, err = jwt.ParseRSAPrivateKeyFromPEM(k)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if out, err := token.SignedString(key); err == nil {
|
||||||
|
fmt.Println(out)
|
||||||
|
clipboard.WriteAll(out)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Error signing token: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
163
token/token.go
Normal file
163
token/token.go
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
// Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package token
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/atotto/clipboard"
|
||||||
|
|
||||||
|
"github.com/manifoldco/promptui"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Helper func: Read input from specified file or string
|
||||||
|
func loadData(p string) ([]byte, error) {
|
||||||
|
if p == "" {
|
||||||
|
return nil, fmt.Errorf("No path or arg specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
var rdr io.Reader
|
||||||
|
if p == "-" {
|
||||||
|
t, _ := clipboard.ReadAll()
|
||||||
|
fmt.Printf("read data from clipboard: %s\n", t)
|
||||||
|
rdr = strings.NewReader(t)
|
||||||
|
} else if p == "+" {
|
||||||
|
return []byte("{}"), nil
|
||||||
|
} else {
|
||||||
|
is, path := isPath(p)
|
||||||
|
if is {
|
||||||
|
if f, err := os.Open(path); err == nil {
|
||||||
|
rdr = f
|
||||||
|
defer f.Close()
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rdr = strings.NewReader(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ioutil.ReadAll(rdr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isPath(path string) (bool, string) {
|
||||||
|
p, err := filepath.Abs("")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
absPath := filepath.Join(p, strings.Replace(path, p, "", 1))
|
||||||
|
_, err = os.Stat(absPath)
|
||||||
|
if err == nil {
|
||||||
|
return true, absPath
|
||||||
|
}
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print a json object in accordance with the prophecy (or the command line options)
|
||||||
|
func printJSON(j interface{}, flagCompact bool) error {
|
||||||
|
var out []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if flagCompact == false {
|
||||||
|
out, err = json.MarshalIndent(j, "", " ")
|
||||||
|
} else {
|
||||||
|
out, err = json.Marshal(j)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
fmt.Println(string(out))
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEs(flagAlg string) bool {
|
||||||
|
return strings.HasPrefix(flagAlg, "ES")
|
||||||
|
}
|
||||||
|
|
||||||
|
func isRs(flagAlg string) bool {
|
||||||
|
return strings.HasPrefix(flagAlg, "RS")
|
||||||
|
}
|
||||||
|
|
||||||
|
func promptAlg() (string, error) {
|
||||||
|
prompt := promptui.SelectWithAdd{
|
||||||
|
Label: "select a signing algorithm identifier",
|
||||||
|
Items: []string{"HS256", "RS256"},
|
||||||
|
AddLabel: "Other",
|
||||||
|
}
|
||||||
|
_, flagAlg, err := prompt.Run()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Prompt flagAlg failed %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return flagAlg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func promptDebug() bool {
|
||||||
|
prompt := promptui.Prompt{
|
||||||
|
Label: "print out all kinds of debug data",
|
||||||
|
IsConfirm: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := prompt.Run(); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func promptCompact() bool {
|
||||||
|
prompt := promptui.Prompt{
|
||||||
|
Label: "output compact JSON",
|
||||||
|
IsConfirm: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := prompt.Run(); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArgList map[string]string
|
||||||
|
|
||||||
|
func (l ArgList) String() string {
|
||||||
|
data, _ := json.Marshal(l)
|
||||||
|
return string(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l ArgList) Set(arg string) error {
|
||||||
|
parts := strings.SplitN(arg, "=", 2)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return fmt.Errorf("Invalid argument '%v'. Must use format 'key=value'. %v", arg, parts)
|
||||||
|
}
|
||||||
|
l[parts[0]] = parts[1]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l ArgList) Type() string {
|
||||||
|
return "argList"
|
||||||
|
}
|
93
token/verifytoken.go
Normal file
93
token/verifytoken.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright © 2018 ehlxr <ehlxr.me@gmail.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package token
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
jwt "github.com/dgrijalva/jwt-go"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Verify a token and output the claims. This is a great example
|
||||||
|
// of how to verify and view a token.
|
||||||
|
func VerifyToken(cmd *cobra.Command) error {
|
||||||
|
flagToken := cmd.LocalFlags().Lookup("token").Value.String()
|
||||||
|
flagKey := cmd.LocalFlags().Lookup("key").Value.String()
|
||||||
|
flagCompact := promptCompact()
|
||||||
|
flagDebug := promptDebug()
|
||||||
|
|
||||||
|
flagAlg, err := promptAlg()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Prompt flagAlg failed %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the token
|
||||||
|
tokData, err := loadData(flagToken)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Couldn't read token: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim possible whitespace from token
|
||||||
|
tokData = regexp.MustCompile(`\s*$`).ReplaceAll(tokData, []byte{})
|
||||||
|
if flagDebug {
|
||||||
|
fmt.Fprintf(os.Stderr, "Token len: %v bytes\n", len(tokData))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the token. Load the key from command line option
|
||||||
|
token, err := jwt.Parse(string(tokData), func(t *jwt.Token) (interface{}, error) {
|
||||||
|
data, err := loadData(flagKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if isEs(flagAlg) {
|
||||||
|
return jwt.ParseECPublicKeyFromPEM(data)
|
||||||
|
} else if isRs(flagAlg) {
|
||||||
|
return jwt.ParseRSAPublicKeyFromPEM(data)
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// Print some debug data
|
||||||
|
if flagDebug && token != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Header:\n%v\n", token.Header)
|
||||||
|
fmt.Fprintf(os.Stderr, "Claims:\n%v\n", token.Claims)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print an error if we can't parse for some reason
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Couldn't parse token: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is token invalid?
|
||||||
|
if !token.Valid {
|
||||||
|
return fmt.Errorf("Token is invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the token details
|
||||||
|
if err := printJSON(token.Claims, flagCompact); err != nil {
|
||||||
|
return fmt.Errorf("Failed to output claims: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user